BZOJ2656 [Zjoi2012]数列(sequence)[模拟]

这个递推式子可以发现$i$是偶数下标可以缩一半,是奇数下标就可以拆成两个下标,$\lfoor \frac{i}{2} \rfloor$以及$\lfoor \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 }

猜你喜欢

转载自www.cnblogs.com/saigyouji-yuyuko/p/11456097.html