BZOJ2656 [Zjoi2012]数列(sequence)[模拟]
这个递推式子可以发现$i$是偶数下标可以缩一半,是奇数下标就可以拆成两个下标,$\lfloor \frac{i}{2} \rfloor$以及$\lfloor \frac{i}{2}+1 \rfloor$。
然后发现每次奇数下标可以拆成一奇一偶,而拆出来的奇再拆和偶的减半得到的下标只有两种。比如:
$A_{13}=1*A_6+1*A_7$
$=1*A_3+1*A_3+1*A_4$
$=2*A_3+1*A_4$
$=2*A_1+2*A_2+1*A_2$
$=2*A_1+3*A_2$
大概就是这个亚子。于是只要记录每次拆出来的两个数$a,b$各需要多少个加起来才能表示原数,
再拆时讨论一下是$b$奇$a$偶,还是$a$奇$b$偶,分两种情况将这个系数累加即可。一直折半到$A_1$停下输出。
高精又WA了一发。。我好菜。WA:line31是b.n。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=50+2,base=1e8,dig=8; 21 struct thx{ 22 int a[N],n; 23 inline void mst(){memset(a,0,sizeof a),n=1;} 24 thx(){mst();} 25 inline int &operator [](int x){return a[x];} 26 inline void get_num(int x){mst(),n=0;while(x)a[++n]=x%base,x/=base;} 27 inline void operator =(int x){get_num(x);} 28 inline thx operator +(thx&orz){ 29 thx b;b.n=_max(n,orz.n); 30 for(register int i=1;i<=b.n;++i)b[i]+=a[i]+orz[i],b[i+1]=b[i]/base,b[i]%=base; 31 while(b[b.n+1]&&++b.n);//mistake! 32 return b; 33 } 34 inline void operator +=(thx&orz){*this=*this+orz;} 35 inline void operator ++(){ 36 ++a[1];int tmp=1; 37 while(a[tmp]==base)a[tmp]=0,++a[++tmp]; 38 while(a[n+1]&&++n); 39 } 40 inline void div2(){ 41 for(register int i=n;i;--i)a[i-1]+=(a[i]&1)*base,a[i]/=2; 42 while(!a[n]&&--n);if(!n)n=1; 43 } 44 inline void read(){ 45 mst(); 46 char s[300+7];scanf("%s",s+1);int len=strlen(s+1); 47 for(register int i=1;dig*(i-1)<len;++i) 48 for(register int j=1,bas=1;j<=_min(dig,len-dig*(i-1));++j,bas*=10)a[i]+=(s[len-dig*(i-1)-j+1]-'0')*bas; 49 n=len/dig+(len%dig!=0); 50 } 51 inline void print(){ 52 printf("%d",a[n]); 53 for(register int i=n-1;i;--i)printf("%08d",a[i]); 54 puts(""); 55 } 56 }val,a,b,x,y,tmp; 57 int T; 58 59 int main(){//freopen("9.in","r",stdin);freopen("9.ans","w",stdout); 60 read(T);while(T--){ 61 val.read(); 62 if(val.n==1&&val[1]==0){puts("0");continue;} 63 while(!(val[1]&1))val.div2(); 64 if(val.n==1&&val[1]==1){puts("1");continue;} 65 val.div2();b=a=val;++b;x=1,y=1; 66 while(!(a.n==1&&a[1]==1)){//printf("x="),x.print(),printf("y="),y.print(); 67 if(a[1]&1)y+=x,a.div2(),b=a,++b; 68 else x+=y,a.div2(),b=a,++b; 69 }//puts("done"); 70 x+=y;x.print(); 71 } 72 return 0; 73 }