hdu 6156 Palindrome Function

数据好像极限,按理来说二分是可以过得,就是被卡主

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#define ll long long
#define pb push_back
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define cls(name,x) memset(name,x,sizeof(name))
#define fs first
#define sc second
#define mp make_pair
#define L(x) (1<<x)
#define next Next
using namespace std;
const int inf=1e9+10;
const ll llinf=1e16+10;
const int maxn=3e3+10;
const int maxm=1e3+10;
const int mod=1e9+7;
int n;
int func(int x,int k)//x在k进制下的位数
{
    int c=0;
    while(x!=0)
    {
        c++;
        x=x/k;
    }
    return c;
}
int check(int key,int t,int l,int r,int k)//key为前半部分下的t位数k进制下的数是否在l,r范围中
{
    int p;
    if(t%2==0) p=key;
    else p=key/k;
    for(int i=(t+1)/2+1;i<=t;i++)
    {
        ll temp=key;
        if(temp*k+p%k>=inf) return 1;
        key=key*k+p%k;
        p=p/k;
    }
    if(key<l) return -1;
    else if(key>r) return 1;
    else return 0;
}
int solvek(int t,int l,int r,int k)//在t位数下,k进制数,有多少个数在l,r中
{
    if(func(l,k)==func(r,k))
    {
        int L=l,R=r;
        int t3,t4;//大于l的最小回文数,和小于r的最大回文数
        for(int i=(t+1)/2+1;i<=t;i++)
        {
            L=L/k;
            R=R/k;
        }
        if(check(L,t,l,r,k)==0) t3=L;
        else t3=L+1;
        if(check(R,t,l,r,k)==0) t4=R;
        else t4=R-1;
        if(t3>t4) return 0;
        else return t4-t3+1;
    }
    else if(t==func(l,k))
    {
        int t2=k-1,t3,L=l;
        for(int i=1;i<(t+1)/2;i++)
            t2=t2*k+(k-1);
        for(int i=(t+1)/2+1;i<=t;i++)
            L=L/k;
        if(check(L,t,l,r,k)==0) t3=L;
        else t3=L+1;
        if(t3>t2) return 0;
        else return t2-t3+1;
    }
    else if(t==func(r,k))
    {
        int t1=1,t4,R=r;
        for(int i=1;i<(t+1)/2;i++)
            t1*=k;
        for(int i=(t+1)/2+1;i<=t;i++)
            R=R/k;
        if(check(R,t,l,r,k)==0) t4=R;
        else t4=R-1;
        if(t1>t4) return 0;
        else return t4-t1+1;
    }
}
ll solve(int l,int r,int k)//k进制下l,r区间有多少回文串
{
    ll c1=0,c2=0;
    int t1=func(l,k),t2=func(r,k);
    for(int i=t1;i<=t2;i++)
    {
        if(i==t1||i==t2)
            c1+=solvek(i,l,r,k);
        else
        {
            ll t=1;
            for(int j=1;j<(i+1)/2;j++)
                t*=k;
            t*=k-1;
            c1+=t;
        }
    }
    c2=(r-l+1)-c1;
    return c1*k+c2;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int l1,r1,l2,r2;
    int ncas,T=1;
    scanf("%d",&ncas);
    while(ncas--)
    {
        scanf("%d %d %d %d",&l1,&r1,&l2,&r2);
        ll ans=0;
        for(int i=l2;i<=r2;i++)
            ans+=solve(l1,r1,i);
        printf("Case #%d: %lld
",T++,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/mgz-/p/7400843.html