这道题题解上写的难度系数2 ,但是我们比赛的时候并没有写出来 - -
思路:
考虑s[n-2]与s[n-1]合并的时候应该需要什么,需要什么我们就求什么
例如:s[5]+s[6] 我们把每个cff往后连算一对,假设我们已经把s[5]和s[6]的答案已经求出来了
那么s[5]中的2个cff需要连到s[6]中的3个cff上,也就是说s[6]中的所有cff与最前端的距离的和需要被算2次,s[5]中所有cff到最后端的距离和要被多算3次
所以我们需要知道:所有cff前缀长度和pf
,cff的个数cn
,串的长度len
,所有cff后缀长度和sf 这四个函数
分别求出来:
设f为斐波那契数列
cn(n)=f(n-2)
len(n)=f(n+1)
pf(n)=cn(n-1)*len(n-2)+sf(n-1)+sf(n-2)
sf(n)=len(n)*cn(n)-sf(n)
ans(n)=cn(n-1)*sf(n-2)+cn(n-2)*pf(n-1)+ans(n-1)+ans(n-2)
想化简得化简一下即可,还是太菜了啊TAT
附:
1
2
3
4
5
6
c
ff
cff
ffcff
cffffcff
ffcffcffffcff
所有cff前缀长度和pf
0
0
0
2
5
17
cff的个数cn
0
0
1
1
2
3
串的长度len
1
2
3
5
8
13
所有cff后缀长度和sf
0
0
3
3
11
22
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300000;
const long long MOD=530600414;
long long f[MAXN];
long long g[MAXN];
long long s[MAXN];
long long mod(long long a)
{
a=a%MOD;
if(a<0) a+=MOD;
return a;
}
void init()
{
///all function start from 1;
f[0]=f[1]=f[2]=1;
for(int i=3;i<MAXN;i++)
f[i]=mod(f[i-1]+f[i-2]);
g[0]=g[1]=g[2]=g[3]=0;
for(int i=4;i<MAXN;i++)
g[i]=mod(g[i-1]+g[i-2]+mod(f[i-3]*f[i-1]));
s[0]=s[1]=s[2]=s[3]=s[4]=0;
for(int i=5;i<MAXN;i++)
s[i]=s[i-1]+s[i-2]+mod(f[i-3]*mod(f[i-1]*f[i-4]-g[i-2]))+mod(f[i-4]*g[i-1]),
s[i]=mod(s[i]);
}
int main()
{
init();
int T,cas=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
printf("Case #%d: %lld\n",cas++,s[n]);
}
return 0;
}