description
出乎意料的是,幸运E 的小R 居然赢了那个游戏。现在欣喜万分的小R 想要写一张明信片给小Y,但是因为小R 非常羞涩,所以他打算采用一些比较神奇的方式来表达。
他定义了一些字符串,s1 = a,s2 = b,si =s_i-1 + s_i-2 (i >=3)。同时他定义了一个字符串s 的权值为一个最大的i <|s|满足s 长度为i 的前缀等于长度为i 的后缀。比如字符串aba 的权值就是1,abab 的权值就是2,aaaa 的权值就是3。
现在小R 在明信片上给出了两个数n 和m,他想要告诉小Y 的信息是字符串sn 的前m个字符组成的字符串的权值。你可以帮小Y 计算一下吗?
analysis
-
打表找规律
-
需要结合打表和出题人九条可怜的温馨提示
-
当nnn最小,且∣s[n]∣>m+1|s[n]|>m+1∣s[n]∣>m+1时,答案即为m−∣s[n−2]∣m-|s[n-2]|m−∣s[n−2]∣
-
那么直接高精度暴力斐波那契数列,暴力判断就好
-
有很多坑点,比如高精度下+1+1+1什么的,调的我爆肝
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1005
#define MAXLEN 305
#define mod 258280327
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
char s[MAXLEN];
ll n,m,T,ans;
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct BIGNUM
{
ll num[MAXLEN],len;
BIGNUM()
{
memset(num,0,sizeof(num)),len=1;
}
BIGNUM operator=(const char s[])
{
len=strlen(s);
fo(i,0,len-1)num[i]=s[len-i-1]-'0';
while (num[len-1]==0 && len>1)--len;
return *this;
}
BIGNUM operator=(const ll x)
{
ll temp=x;
len=1;
do
{
num[len-1]=temp%10;
temp/=10,len++;
}while (temp);
while (num[len-1]==0 && len>1)--len;
return *this;
}
BIGNUM operator+(const BIGNUM &x)const
{
BIGNUM temp;
temp.len=max(len,x.len)+1;
fo(i,0,temp.len-1)
{
temp.num[i]+=num[i]+x.num[i];
temp.num[i+1]=temp.num[i]/10;
temp.num[i]%=10;
}
while (temp.num[temp.len-1]==0 && temp.len>1)--temp.len;
return temp;
}
BIGNUM operator-(const BIGNUM &x)const
{
BIGNUM temp;
temp.len=max(len,x.len);
fo(i,0,temp.len-1)
{
temp.num[i]+=num[i]-x.num[i];
if (temp.num[i]<0)temp.num[i]+=10,--temp.num[i+1];
}
while (temp.num[temp.len-1]==0 && temp.len>1)--temp.len;
return temp;
}
BIGNUM operator*(const BIGNUM &x)const
{
BIGNUM temp;
temp.len=len+x.len;
fo(i,0,len-1)
{
fo(j,0,x.len-1)
{
temp.num[i+j]+=num[i]*x.num[j];
temp.num[i+j+1]+=temp.num[i+j]/10;
temp.num[i+j]%=10;
}
}
while (temp.num[temp.len-1]==0 && temp.len>1)--temp.len;
return temp;
}
bool operator<(const BIGNUM &x)const
{
if (len>x.len)return 0;
if (len<x.len)return 1;
fd(i,len-1,0)if (num[i]!=x.num[i])return num[i]<x.num[i];
return 0;
}
void print()
{
fd(i,len-1,0)printf("%lld",num[i]);
printf("\n");
}
}f[MAXN],temp,tempp,one;
O3 int main()
{
//freopen("T3.in","r",stdin);
T=read();
f[1]=f[2]=one=1;
fo(i,3,MAXN-2)f[i]=f[i-1]+f[i-2];
while (T--)
{
n=read(),scanf("%s",&s),temp=tempp=s;
tempp.num[0]++,tempp.num[tempp.len]=0;
fo(i,0,tempp.len-1)if (tempp.num[i]>9)tempp.num[i+1]++,tempp.num[i]-=10;else break;
if (tempp.num[tempp.len])tempp.num[++tempp.len]=1;
fo(i,1,MAXN+2)
{
if (tempp<f[i])
{
temp=temp-f[i-2];
ans=0;
fd(i,temp.len-1,0)
{
ans=ans*10+temp.num[i];
ans%=mod;
}
printf("%lld\n",ans%mod);
break;
}
}
}
return 0;
}