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\n",T++,ans); } return 0; }