[CQOI2018]九连环
题目:洛谷P4461、BZOJ5300。
题目大意:
求\(\lfloor\frac{2^{n+1}}{3} \rfloor\)
解题思路:
压位高精即可。
C++ Code:
#include<bits/stdc++.h> #define LoveLive long long #define md 100000000 inline int readint(){ int c=getchar(),d=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) d=(d<<3)+(d<<1)+(c^'0'); return d; } LoveLive ans[5000],a[5000],c[5000]; int wans,wa; int main(){ for(int m=readint(),n;m--;){ n=readint()+1; memset(a,0,sizeof a); 1[a]=2; memset(ans,0,sizeof ans); 1[ans]=1; wans=wa=1; while(n){ if(n&1){ memset(c,0,sizeof c); for(int i=1;i<=wans;++i) for(int j=1;j<=wa;++j){ c[i+j-1]+=ans[i]*a[j]; c[i+j]+=c[i+j-1]/md; c[i+j-1]%=md; } wans=wans+wa-1; while(c[wans+1])++wans; while(!c[wans])--wans; memcpy(ans,c,sizeof ans); } memset(c,0,sizeof c); for(int i=1;i<=wa;++i) for(int j=1;j<=wa;++j){ c[i+j-1]+=a[i]*a[j]; c[i+j]+=c[i+j-1]/md; c[i+j-1]%=md; } wa=wa*2-1; while(c[wa+1])++wa; while(!c[wa])--wa; memcpy(a,c,sizeof c); n>>=1; } memset(c,0,sizeof c); for(int i=wans;i;--i){ ans[i]+=ans[i+1]*md; c[i]=ans[i]/3; ans[i]%=3; } while(!c[wans])--wans; printf("%d",(int)c[wans]); for(int i=wans-1;i;--i)printf("%08d",(int)c[i]); putchar('\n'); } }