分析
SB规律题
我考场发现了错误规律
打了2h+
因为T1T2不可做
设n为最小的满足f[n]>m+1
那么答案为m-f[n-2]
高精
别问我怎么推的,没有人推出来,dalao都说显然
The love to you is deep in s.
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const ll P=258280327ll; const ll G=1e5; int T,n; struct LJGJD { ll a[1010]; int len; void clear() { for (int i=0;i<1010;i++) a[i]=0;len=0; } }m,f[1010]; LJGJD Plus(LJGJD x,LJGJD y) { LJGJD a=x,b=y,c;c.clear(); for (int i=1;i<=max(a.len,b.len);i++) { c.a[i]+=a.a[i]+b.a[i]; c.a[i+1]+=c.a[i]/G; c.a[i]%=G; } c.len=max(a.len,b.len); if (c.a[c.len+1]) c.len++; return c; } LJGJD Sub(LJGJD x,LJGJD y) { LJGJD a=x,b=y,c;c.clear(); for (int i=1;i<=max(a.len,b.len);i++) { c.a[i]+=a.a[i]-b.a[i]; while (c.a[i]<0) c.a[i]+=G,c.a[i+1]--; } c.len=max(a.len,b.len); while (!c.a[c.len]) c.len--; return c; } bool Bigger(LJGJD x,LJGJD y) { if (x.len<y.len) return 0; if (x.len>y.len) return 1; for (int i=x.len;i;i--) if (x.a[i]>y.a[i]) return 1; else if (x.a[i]<y.a[i]) return 0; return 0; } ll Mod(LJGJD x) { ll ans=0,g=G%P; for (int i=x.len;i;i--) ans=(ans*g+x.a[i]%P)%P; return ans; } int main() { f[1].a[1]=f[2].a[1]=1ll;f[1].len=f[2].len=1; for (int i=3;i<=1001;i++) f[i]=Plus(f[i-1],f[i-2]); for (scanf("%d",&T);T;T--) { char c[10010]; int len=0;ll k=1ll; scanf("%d%s",&n,c+1);len=strlen(c+1); m.clear();m.len=1; for (int i=len;i;i--) { m.a[m.len]+=(c[i]-'0')*k;k*=10ll; if (k==G&&i!=1) k=1ll,m.len++; } if (n==1||n==2||n==3||(m.len==1&&(m.a[1]==1||m.a[1]==2))) { printf("0\n"); continue; } LJGJD w=m;m=Plus(m,f[1]); for (int i=4;i<=n+1;i++) if (Bigger(f[i],m)) { w=Sub(w,f[i-2]); ll ans=Mod(w); printf("%lld\n",ans); break; } } }