HDU-5459 Jesus Is Here(思维递推)

来源:互联网 发布:js获取input的type 编辑:程序博客网 时间:2024/05/20 04:14

题意:

求串s[n]中所有字符‘c'之间的坐标差的和。

思路:

可以发现一个串中c的个数和该串的长度都是一个斐波那契数,然后分析当前串s[n]对应的答案F[n],首先F[n-1]+F[n-2]是答案的一部分值,再看当前串和前面两个串的关系,得到剩余的部分值等于s[n-2]串中的c的个数*s[n-1]中所有c到开头的距离之和,再加上s[n-1]串中的c的个数*s[n-2]中所有c到末尾的距离之和,从而这样就覆盖了所有的组合情况。

代码:

#include <bits/stdc++.h>#define LL long longusing namespace std;const LL mod = 530600414;const int maxn = 201315;LL ans[maxn];LL f[maxn], pre[maxn], las[maxn];LL cnt[maxn];int t, n;void init(){ans[3] = ans[4] = 0;f[3] = 3, f[4] = 5;pre[3] = 1, pre[4] = 3;las[3] = 2, las[4] = 2;//把c只归为到到末尾的部分,或者到开头的部分,避免重复统计 //pre[3] = 0, pre[4] = 2;//las[3] = 3, las[4] = 3;cnt[3] = cnt[4] = 1;for(int i = 5; i <= 201314; ++i){f[i] = (f[i-1]+f[i-2])%mod;cnt[i] = (cnt[i-1]+cnt[i-2])%mod;pre[i] = (pre[i-1]+f[i-2]*cnt[i-1]%mod+pre[i-2])%mod;las[i] = (las[i-2]+f[i-1]*cnt[i-2]%mod+las[i-1])%mod;ans[i] = ((ans[i-1]+ans[i-2])%mod+pre[i-1]*cnt[i-2]%mod+las[i-2]*cnt[i-1]%mod)%mod;}}int main(){init(); scanf("%d", &t);for(int _ = 1; _ <= t; ++_){scanf("%d", &n);printf("Case #%d: %lld\n", _, ans[n]);}return 0;}


继续加油~

原创粉丝点击