[數位dp] HDU 6156 Palindrome Function
阿新 • • 發佈:2020-09-19
題目大意
定義函式 \(f(n,k)\),當 \(n\) 在 \(k\) 進位制下為迴文數時,\(f(n,k)=k\),不是迴文數是 \(f(n,k)=1\)。給定 \(L,R,l,r(1\leq L\leq R\leq 10^9,2\leq l\leq r\leq 36)\),求\(\sum_{i=L}^R\sum_{j=l}^r f(i,j)\)。
題解
數位dp。設 \(dp[base][pos][len]\) 表示在 \(base\) 進位制下,列舉到第 \(pos\) 位,不含前導零的數字的長度為 \(len\) 時的迴文數個數。
Code
#include <iostream> #include <algorithm> #include <cstring> #include <string> #include <cstdio> #include <vector> #include <map> using namespace std; #define RG register int #define LL long long template<typename elemType> inline void Read(elemType &T){ elemType X=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); T=(w?-X:X); } LL dp[37][33][50]; int a[100],Num[50]; int T,Base; LL DFS(int pos,bool limit,bool lead,int Len){ if(!pos) return Len?1:0; if(!limit && !lead && dp[Base][pos][Len]!=-1) return dp[Base][pos][Len]; int up=limit?a[pos]:(Base-1); LL Res=0; for(int i=0;i<=up;++i){ if(lead && i==0){ Res+=DFS(pos-1,limit && i==up,true,Len-1); continue; } if((Len&1) && pos==((Len+1)>>1)) Res+=DFS(pos-1,limit && i==up,lead && i==0,Len); else if(Len-pos>=Len/2){ if(i!=Num[Len-pos+1]) continue; Res+=DFS(pos-1,limit && i==up,lead && i==0,Len); }else{ Num[pos]=i; Res+=DFS(pos-1,limit && i==up,lead && i==0,Len); } } if(!limit && !lead) dp[Base][pos][Len]=Res; return Res; } LL Solve(LL x,LL base){ int pos=0; while(x){a[++pos]=x%base;x/=base;} return DFS(pos,true,true,pos); } int main(){ memset(dp,-1,sizeof(dp)); LL L,R,l,r; Read(T);int Case=0; while(T--){ Read(L);Read(R);Read(l);Read(r); LL Ans=0; for(LL k=l;k<=r;++k){ Base=k; LL temp=Solve(R,k)-Solve(L-1,k); Ans+=temp*k+(R-L+1-temp); } printf("Case #%d: %lld\n",++Case,Ans); } return 0; }