[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');
	}
}

 

posted @ 2018-06-16 12:57  Mrsrz  阅读(253)  评论(0编辑  收藏  举报