【五校联考1day2】对你的爱深不见底(斐波那契数列+高精度加、减、模)
思路
这一类的字符串的特殊性还是挺明显的,打一个表或者找规律就可以发现.
令Si为斐波那契数列第i项,由于会爆long long,要用高精度加减、取模。
令 n 为最小的 n 满足 |Sn| > m+1,那么答案就是 m−|Sn−2|。证明还是挺简单的大家脑补一下就好了。时间复杂度 O(N^2 )。
CODE
借鉴code很可能不被你的OI老师所允许,请慎重选择
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 int n,t,mod=258280327; 7 struct node 8 { 9 int s[10005],len; 10 void read() 11 { 12 char ch=getchar(); 13 len=0; 14 while(ch<'0'||ch>'9')ch=getchar(); 15 while(ch>='0'&&ch<='9') 16 { 17 s[len++]=ch-48; 18 ch=getchar(); 19 } 20 for(int j=0;j<len/2;j++) 21 { 22 swap(s[j],s[len-j-1]); 23 } 24 } 25 void wrt() 26 { 27 for(int i=len-1;i>=0;i--) 28 { 29 printf("%d",s[i]); 30 } 31 printf("\n"); 32 } 33 }a[3005],m,ans,tmp; 34 node sum(node x,node y) 35 { 36 node s;s.len=max(x.len,y.len)+3; 37 for(int i=0;i<max(x.len,y.len)+5;i++)s.s[i]=0; 38 int last=0; 39 for(int i=0;i<max(x.len,y.len);i++) 40 { 41 s.s[i]=(x.s[i]+y.s[i]+last)%10; 42 last=(x.s[i]+y.s[i]+last)/10; 43 } 44 if(last)s.s[max(x.len,y.len)]=last; 45 s.len=max(x.len,y.len)+3; 46 while(s.s[s.len]==0)s.len--; 47 s.len++;return s; 48 } 49 node del(node x,node y) 50 { 51 node s; 52 for(int i=0;i<max(x.len,y.len)+5;i++)s.s[i]=0; 53 int last=0; 54 for(int i=0;i<max(x.len,y.len);i++) 55 { 56 if(x.s[i]>=y.s[i]+last) 57 { 58 s.s[i]=x.s[i]-y.s[i]-last; 59 last=0; 60 } 61 else 62 { 63 s.s[i]=10+x.s[i]-y.s[i]-last; 64 last=1; 65 } 66 } 67 s.len=max(x.len,y.len)+3; 68 while(s.s[s.len]==0)s.len--; 69 s.len++; 70 return s; 71 } 72 int modit(node x) 73 { 74 long long a=0,b=mod; 75 for(int i=x.len;i>=0;i--) 76 { 77 a=a*10+x.s[i]; 78 if(a>=b) 79 { 80 a=a%b; 81 } 82 } 83 return a; 84 } 85 bool check(node x,node y) 86 { 87 if(x.len>y.len)return 1; 88 if(x.len<y.len)return 0; 89 bool bz=0; 90 for(int i=x.len-1;i>=0;i--) 91 { 92 if(x.s[i]>y.s[i]){bz=1;break;} 93 if(x.s[i]<y.s[i]){bz=0;break;} 94 } 95 return bz; 96 } 97 void init() 98 { 99 a[1].s[a[1].len++]=1; 100 a[2].s[a[2].len++]=1; 101 } 102 int main() 103 { 104 init(); 105 for(int i=3;i<=2000;i++) 106 { 107 a[i]=sum(a[i-1],a[i-2]); 108 } 109 for(scanf("%d",&t);t--;) 110 { 111 scanf("%d",&n); 112 m.read(); 113 for(int i=1;i<=2000;i++) 114 { 115 if(check(a[i],sum(m,a[1]))) 116 { 117 ans=del(m,a[i-2]); 118 break; 119 } 120 } 121 printf("%d\n",modit(ans)); 122 } 123 }