hdu5459

来源:互联网 发布:C语言下列叙述错误的是 编辑:程序博客网 时间:2024/06/16 09:36

题目链接:hdu5459


题目分析:求第n项中所有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]的值。对于后面的情况即是所有的ai-bj相加之和(ai表示a中第i个c的坐标,bi表示b中第j个c的坐标),不难看出i的最大值为a中c的个数,j的最大值为b中c的个数。那么如果我们从a中选出的c为第i个的情况有多少种呢?不难看出即为b中c的个数。

所以对于这个式子我们可以改写成所有情况中所有从a选取的c的坐标和,减去从b选取c的坐标和(这里的坐标可以认作他们的位置,但是对于b来说,它的坐标为为它在b中的位置加上a的长度)。所以式子可以化简为:(x[i-1]+num[i-1]*len[i-2])*num[i-2]-x[i-2]*num[i-1]。


代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef long long LL;const int maxn=300000;const int mod=530600414;int T,n,Case;LL x[maxn];     //c的坐标和LL num[maxn];   //c的个数LL len[maxn];   //s[i]的长度LL ans[maxn];   //答案void init(){    x[5]=7;x[6]=20;    num[5]=2;num[6]=3;    ans[5]=5;ans[6]=16;    len[5]=8;len[6]=13;    for(int i=7;i<maxn;i++){        num[i]=(num[i-2]+num[i-1])%mod;        len[i]=(len[i-2]+len[i-1])%mod;        x[i]=(x[i-2]+x[i-1]+num[i-1]*len[i-2]%mod)%mod; //第(i-1)个字符串里的c坐标都要加上第(i-2)个串的长度        ans[i]=(ans[i-2]+ans[i-1]+(x[i-1]+num[i-1]*len[i-2])%mod*num[i-2]-x[i-2]*num[i-1]%mod)%mod;    }}int main(){//    freopen("in.txt","r",stdin);    for(init(),scanf("%d",&T),Case=1;T--;Case++){        scanf("%d",&n);        printf("Case #%d: %lld\n",Case,ans[n]);    }    return 0;}