您的位置:首页 > 其它

hdu 5459 Jesus Is Here(厉害的递推)

2015-09-20 01:59 344 查看
题意:字符串s[1]="c",s[2]="ff",s[i]=s[i-2]+s[i-1](i>=3);

对于每个n,求s
中所有的任意两个字符c的距离之和;

参考:http://blog.csdn.net/u012762625/article/details/48580167

思路:比赛时没思路。用dp[i]表示s[i]的结果,dist[i]表示s[i]中所有c到s[i]末尾的距离之和,len[i]表示s[i]的长度,cnt[i]表示s[i]中c的数量;

dp[i]=dp[i-1]+dp[i-2]+cnt[i-1]*dist[i-2]+cnt[i-2]*((len[i-1]*cnt[i-1])-dist[i-1]);

即两边独立的距离与两边相互关联的距离和;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mod 530600414
int t,n,m;
long long dp[500010];
long long cnt[500010],len[500010],dist[500010];
void init(){
int i,j,k;
cnt[1]=1,cnt[2]=0;
len[1]=1,len[2]=2;
dist[1]=0,dist[2]=0,dist[3]=dist[4]=2;
dp[1]=dp[2]=dp[3]=dp[4]=0,dp[5]=5;
for(i=3;i<=300000;i++){
cnt[i]=(cnt[i-1]%mod+cnt[i-2]%mod)%mod;
len[i]=(len[i-1]%mod+len[i-2]%mod)%mod;
}
for(i=5;i<=300000;i++){
dist[i]=(dist[i-1]%mod+dist[i-2]%mod+(cnt[i-2]%mod*len[i-1]%mod)%mod)%mod;
}
for(i=6;i<=300000;i++){
dp[i]=(dp[i-1]%mod+dp[i-2]%mod+(cnt[i-1]%mod*dist[i-2]%mod)%mod+(cnt[i-2]%mod*(len[i-1]%mod*cnt[i-1]%mod-dist[i-1]%mod)%mod)%mod)%mod;
}
}
int main(){
int i,j,k;
init();
scanf("%d",&t);
for(k=1;k<=t;k++){
scanf("%d",&n);
printf("Case #%d: ",k);
printf("%I64d\n",dp
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: