Palindrome Function

题目飞机直达
题目:Palindrome Function
题意:求sigma(f(i,j)),L<=i<=R, l<=j<+r, 2<=l<=36, 1<=L<=R<=1e9; 数据组数可达1e5;
f(i, j)=: j, j进制下i是回文数字,
1, j进制下i不是回文数字.
思路:由于数据组数太大了, 所以考虑得出结果应该不费劲.这说明要么是结论题,要么需要大量的预处理,或者是要用到记忆化什么的.
任意进制下1e9以内的回文数会有多大呢?不可能超过1e5个吧, 因为回文数的半边一定是不相同的数, 那就好办了。可以把所有进制
下的回文数全部构造出来(就枚举一边就行了,想想就知道不会有重复), 然后排个序, 对每个询问每个进制进行两次二分查找
就可以轻松得到答案。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
int const maxa=1e9+0.2;
int num[100];
vector<int> G[40];

void init()
{
    for (int i=1; i<=200000; i++){
        //一开始i到100000 Wa了, 改大一些莫名就A了...至今想不明白到100000怎么会漏掉的呢, 如果有同学知道麻烦告知一声
        for (int b=2; b<=36; b++){
            int p=0, t=i;
            while (t>0){
                num[p++]=t%b;
                t/=b;
            }
            LL a1=i, a2=i*b+num[0];//a2偶数位,  a1奇数位(最后一个数字只取一次)
            for (int j=1; j<p; j++){
                a1=a1*b+num[j];
                a2=a2*b+num[j];
            }
            //a1, a2在b进制下一定是回文数
            if (a1<=maxa) G[b].push_back(a1);
            if (a2<=maxa) G[b].push_back(a2);
        }
    }
    for (int b=2; b<=36; b++) {
        sort(G[b].begin(), G[b].end());
    }

}
int main(void){
    init();
    int T, ca=1, L, R, l, r;
    for (scanf("%d", &T); T; T--){
        scanf("%d%d%d%d", &L, &R, &l, &r);
        LL ans=0;
        for (int b=l; b<=r; b++){
            int len=upper_bound(G[b].begin(), G[b].end(), R)-lower_bound(G[b].begin(), G[b].end(), L);
            //得到b进制下,[L, R]的回文数
            ans+=b*len+(R+1-L-len);

        }
        printf("Case #%d: %I64d\n", ca++, ans);
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值