题意: 给定一个斐波那契字符串 Si=Si-1+Si-2
求第i项中 两两c的坐标的距离之和
思路:s[i]=s[i-1]+s[i-2],第i个字符串中的c字符可以分为两部分,来自第i-2个字符串(姑且叫做a)的和第i-1个字符串(姑且叫做b)。既然如此我们对于答案,也可以分几部分求出,a中的c坐标差的和,b中的c坐标差的和,以及两个c,一个来自a一个来自b的所有情况的坐标差的和。
前面两个很容易得到,就是ans[i-2]和ans[i-1]的值。对于后面的情况即是所有的bj-ai相加之和(ai表示a中第i个c的坐标,bi表示b中第j个c的坐标).
那么如果我们从a中选出的c为第i个的情况有多少种呢?不难看出即为b中c的个数
这里我们假定a中某个c的贡献只考虑b中c减a中c,那么a中某个c的贡献就是b中c的坐标和-a中那个c的坐标和。
所以对于这个式子我们可以改写成所有情况中所有从a选取的c的坐标和,减去从b选取c的坐标和(这里的坐标可以认作他们的位置,但是对于b来说,它的坐标为为它在b中的位置加上a的长度)。所以式子可以化简为:(sum[i-1]+num[i-1]*len[i-2])*num[i-2]-sum[i-2]*num[i-1]。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int mod=530600414;
const int maxn=222222;
ll len[maxn],num[maxn],sum[maxn],ans[maxn];
int main()
{
len[1]=1;
len[2]=2;
num[1]=1;num[2]=0;
ans[5]=5;ans[6]=16;
sum[5]=7;sum[6]=20;
for(int i=3;i<=201314;i++)
len[i]=(len[i-1]+len[i-2])%mod,num[i]=(num[i-1]+num[i-2])%mod;
for(int i=7;i<=201314;i++)
sum[i]=(sum[i-1]+sum[i-2]+(num[i-1]*len[i-2])%mod)%mod;
for(int i=7;i<=201314;i++)
ans[i]=(ans[i-1]+ans[i-2]+((sum[i-1]+(num[i-1]*len[i-2])%mod)%mod*num[i-2])%mod-(num[i-1]*sum[i-2])%mod)%mod;
int t;
cin>>t;
int ok=1;
while(t--)
{
int n;
cin>>n;
printf("Case #%d: ",ok++);
cout<<(ans[n]+mod)%mod<<endl;
}
return 0;
}