Palindrome Function
题意:L到R之间的数x,写成k进制(l<=k<=r)后,如果是回文串,那么f(x,k)=k,否则f(x,k)=1,对f求和。
数位dp
dp[len][cur][sta][k] 长度、当前位置、是否是回文、k进制
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 ll dp[35][35][2][38]; 5 int bit[35]; 6 int num[35]; 7 int L,R,l,r; 8 9 ll dfs(int len,int cur,int sta,int lim,int k){ 10 if(cur<0){ 11 if(sta) return k; 12 else return 1; 13 } 14 if(!lim&&dp[len][cur][sta][k]!=-1) return dp[len][cur][sta][k]; 15 int up=lim?bit[cur]:k-1; 16 ll ans=0; 17 for(int i=0;i<=up;i++){ 18 num[cur]=i; 19 if(len==cur&&i==0) ans+=dfs(len-1,cur-1,sta,lim&&i==up,k); 20 else if(sta&&cur<(len+1)/2) ans+=dfs(len,cur-1,sta&&i==num[len-cur],lim&&i==up,k); 21 else ans+=dfs(len,cur-1,sta,lim&&i==up,k); 22 } 23 if(!lim) dp[len][cur][sta][k]=ans; 24 return ans; 25 } 26 ll solve(int x){ 27 ll ans=0; 28 for(int i=l;i<=r;i++){ 29 int pos=0; 30 int temp=x; 31 while(temp){ 32 bit[pos++]=temp%i; 33 temp/=i; 34 } 35 ans+=dfs(pos-1,pos-1,1,1,i); 36 } 37 return ans; 38 } 39 40 int main(){ 41 int t,kase=0; 42 memset(dp,-1,sizeof(dp)); 43 scanf("%d",&t); 44 while(t--){ 45 scanf("%d%d%d%d",&L,&R,&l,&r); 46 printf("Case #%d: ",++kase); 47 printf("%lld\n",solve(R)-solve(L-1)); 48 } 49 return 0; 50 }