acdream 1116 Gao the string! (扩展kmp,dp思想,矩阵优化)

来源:互联网 发布:java配置文件怎么写 编辑:程序博客网 时间:2024/05/11 03:29

题意:

题目要求每个后缀能包含多多少前缀,只不过这个数作为斐波那契的下标,求出对应斐波那契的和。

题解:

首先对于要计算出对应的后缀包含多少前缀,如果单单指考虑这样某个后缀能和多少前缀重合,可以通过扩展kmp求得。因为是求后缀对应的某个子串能包含多少前缀,因此要从后往前递推累加,然后同时计算对应的斐波那契数。开始的时候打斐波那契数的表,想找到循环节通过模处理,但是太大了,打不了,开始还因为这个re了几发,其实算了下复杂度2^3*log(n)完全可以用矩阵乘法搞,然后就O(nlong(n))水水的过了。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>#define B(x) (1<<(x))using namespace std;typedef long long ll;typedef unsigned long long ull;void cmax(int& a, int b){ if (b>a)a = b; }void cmin(int& a, int b){ if (b<a)a = b; }void cmax(ll& a, ll b){ if (b>a)a = b; }void cmin(ll& a, ll b){ if (b<a)a = b; }void add(int& a, int b, int mod){ a = (a + b) % mod; }void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }const int oo = 0x3f3f3f3f;const ll OO = 0x3f3f3f3f3f3f3f3f;const ll MOD = 1000000007;const int maxn = 110000;char s[maxn];ll Next[maxn];struct Marix{ll a[2][2];Marix(){ memset(a, 0, sizeof a); }};Marix Mutil(const Marix &a, const Marix &b){Marix c;for (int i = 0; i < 2; i++){for (int j = 0; j < 2; j++){for (int k = 0; k < 2; k++)c.a[i][j] += a.a[i][k] * b.a[k][j];c.a[i][j] %= MOD;}}return c;}ll Pow(Marix a, ll k){Marix ans;ans.a[0][0] = ans.a[1][1] = 1;while (k){if (k & 1) ans = Mutil(a, ans);a = Mutil(a, a);k >>= 1;}return ans.a[1][0];}void get_extend(char T[], int len){int k = 0;Next[0] = len;while (k<len - 1 && T[k] == T[k + 1])k++;Next[1] = k;k = 1;for (int i = 2; i<len; i++){int p = k + Next[k] - 1, L = Next[i - k];///p表示目前匹配的最大长度if (i + L - 1 >= p)///大于,要更新{int j = max(p - i + 1, 0);while (i + j<len&&T[i + j] == T[j])j++;Next[i] = j;k = i;}else Next[i] = L;}}int main(){Marix a;a.a[0][0] = 1; a.a[0][1] = 1;a.a[1][0] = 1; a.a[1][1] = 0;while (scanf("%s", s) != EOF){int len = strlen(s);get_extend(s, len);ll ans = Pow(a, Next[len - 1]);for (int i = len - 2; i >= 0; i--){Next[i] += Next[i + 1];ans += Pow(a, Next[i]);ans %= MOD;}cout << ans << endl;}return 0;}



0 0
原创粉丝点击