HDU6156 Palindrome Function

题意:输入L,R,l,r求[L,R]范围内在[l, r]进制下的回文数(2<=l<=r<=26, L<=R<1e9)

题解:主要是求回文数,枚举每个进制,求ans = R前面的回文数-L前面的回文数,可以发现每个进制下小于1e9的回文数比较少,直接把所有的回文数预处理排序二分就可以

#include <bits/stdc++.h>
#define ll long long
#define maxn 100100
#define BUG(x, n) for(ll i=0;i<=n;i++) cout<<x[i]<<" ";cout<<endl;
using namespace std;
ll temp[100];
vector<ll >vec[40];
ll mmp(ll x,ll t,ll k){
    ll num=0, ans = 0;
    while(x){
        temp[++num] = x%t;
        x /= t;
    }
    for(ll i=num;i>=1;i--) ans = ans*t+temp[i];
    if(k!=-1) ans = ans*t+k;
    for(ll i=1;i<=num;i++) ans = ans*t+temp[i];
    return ans;
}
void init(){
    ll t1 = 0;
    for(ll i=2;i<=36;i++)
        for(ll j=0;j<i;j++)
            vec[i].push_back(j);
    for(ll j=2;j<=36;j++)
        for(ll i=1;;i++){
            t1 = mmp(i, j, -1);
            if(t1>1e9) break;
            vec[j].push_back(t1);
        }

        for(ll j=2;j<=36;j++)
            for(ll k=0;k<j;k++)
                for(ll i=1;;i++){
                t1 = mmp(i, j, k);
                if(t1>1e9) break;
                vec[j].push_back(t1);
            }
    for(ll i=2;i<=36;i++)
        sort(vec[i].begin(), vec[i].end());
}
int main(){
    init();
    ll T, L, R, l, r, ans, RR, LL, num = 1;
    scanf("%lld", &T);
    while(T--){
        ans = 0;
        scanf("%lld%lld%lld%lld", &L, &R, &l, &r);
        for(ll i=l;i<=r;i++){
            RR = upper_bound(vec[i].begin(), vec[i].end(), R)-vec[i].begin()-1;
            LL = upper_bound(vec[i].begin(), vec[i].end(), L-1)-vec[i].begin()-1;
            ans += (RR-LL)*(i-1)+(R-L+1);
        }
        printf("Case #%lld: %lld
", num++, ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/7399284.html