#數位dp,高精度#洛谷 2235 [HNOI2002]Kathy函式
阿新 • • 發佈:2020-08-18
分析
首先這個\(f\)函式其實求的是二進位制下的迴文數,簡單證明一下
設\(n\)在二進位制下的迴文數為\(n'\),第一二條顯然
第三條\(f(2n)=f(n)\Rightarrow \overline {0} n'=n'\),很好證明
第四條\(f(4n+1)=2f(2n+1)-f(n)\Rightarrow \overline {10}n'=\overline{1}n'\overline{0}-n'=\overline{10}n'\)
第五條
\[f(4n+3)=3f(2n+1)-2f(n)=2(2f(2n+1)-f(n))-f(2n+1)=2f(4n+1)-f(2n+1) \]
\[\Rightarrow\overline{11}n'=\overline{10}n'\overline{0}-\overline{1}n'=\overline{11}n' \]
得證,對於位數小於\(n\)的位數答案,易求
對於位數等於\(n\)的位數的答案,特判\(n\)是否為迴文數
給出一個虛擬碼
inline bool mxcheck(lll m,lll len){ rr int j=len/2,i=len-j-1; for (;i>=0&&j<len;--i,++j){ if (((m>>i)&1)>((m>>j)&1)) return 1; if (((m>>i)&1)<((m>>j)&1)) return 0; } return 1; } signed main(){ scanf("%lld",&m); for (len=1,n=1;n<m;++len,n=n<<1|1) ans+=1ll<<((len-1)/2); ans+=(m&(n>>1))>>(len>>1); if (mxcheck(m,len)) ++ans; printf("%lld\n",ans); }
改成高精度就可以A了
程式碼
#include <cstdio> #include <cctype> #define rr register #define mod 1000000000 using namespace std; int len,Ans,a[351],ans[351],Q[101],Qlen; inline void add_one(int *a,int now,int &len){//在二進位制的某一位加1 for (;a[now];++now) a[now]=0; a[now]=1; if (now>=len) len=now+1; } inline bool mxcheck(){ rr int j=len/2,i=len-j-1; for (;i>=0&&j<len;--i,++j) if (a[i]!=a[j]) return a[i]>a[j]; return 1; } inline void innput(){ rr char c=getchar(); for (;!isdigit(c);c=getchar()); for (;isdigit(c);c=getchar()){ rr int w=c^48,t=0; if (len){ len+=3; for (rr int j=len-1;~j;--j){ a[j]=0; if (j>=3&&a[j-3]) add_one(a,j,len); if (j>=1&&a[j-1]) add_one(a,j,len); } } for (;w;w>>=1,++t) if (w&1) add_one(a,t,len); } } signed main(){ innput(); for (rr int i=0;i<len-1;++i) add_one(ans,i>>1,Ans); for (rr int i=len/2,j=0;i<len-1;++i,++j) if (a[i]) add_one(ans,j,Ans); if (mxcheck()) add_one(ans,0,Ans); for (rr int i=Ans-1;~i;--i){//將二進位制轉換為十進位制 rr int g=0; for (rr int j=0;j<Qlen;++j){ rr int s=Q[j]*2+g; g=s/mod,Q[j]=s%mod; } if (g) Q[Qlen++]=g; g=ans[i]; rr int t=0; for (;g;++t) g=(++Q[t])/mod; if (t>Qlen) Qlen=t; } printf("%d",Q[Qlen-1]); for (rr int i=Qlen-2;~i;--i) printf("%09d",Q[i]); return 0; }