Problem Description

give you a string, please output the result of the following function mod 1000000007

n is the length of the string

f() is the function of fibonacci, f(0) = 0, f(1) = 1...

a[i] is the total number of times any prefix appear in the suffix s[i....n-1].

(the prefix means s[0...i] )

解法:假设知道了num[i]表示i開始的后缀s[i....n]跟前缀s[1...]之间的公共的前缀,那么以i开头的后缀中就匹配了num[i]个前缀了

所以i这个后缀出现的前缀的数量实际上就是num[i] + num[i+1] + .. num[n]. 求出来之后高速幂求斐波那契数列对应项大小就可以。求lcp的时候是二分+hash;字符串hash中,seed为31(java库源代码中是这个数,应该是效果比較好的)

代码:

/******************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std; #define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef long long LL;
const int Max=100010;
const int INF=1000000007;
const int hashseed=31; LL seed[Max];
LL has[Max];
char s[Max];
LL num[Max];
int len=0;
struct matrix
{
LL num[2][2];
matrix()
{
memset(num,0,sizeof num);
}
};
matrix operator*(const matrix& a,const matrix& b)
{
matrix ans;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
ans.num[j][k]+=(a.num[j][i]*b.num[i][k])%INF;
return ans;
}
matrix operator^(matrix a,LL n)
{
matrix ans;
ans.num[0][0]=1;
ans.num[1][1]=1;
while(n)
{
if(n&1)
{
ans=ans*a;
}
a=a*a;
n>>=1;
}
return ans;
}
LL getans(LL t)
{
if(t==0)
return 0;
if(t<=2)
return 1;
matrix tool;
tool.num[0][0]=1;
tool.num[0][1]=1;
tool.num[1][0]=1;
tool=tool^(t-1);
return tool.num[0][0]%INF;
}
void init()
{
seed[0]=1;
for(int i=1; i<Max; i++)
seed[i]=(seed[i-1]*hashseed)%INF;
}
LL Hash(int i,int L)
{
return ((has[i]-has[i+L]*seed[L])%INF+INF)%INF;
}
bool OK(int i,int l)
{
return Hash(0,l)==Hash(i,l);
}
void getnum(int i)
{
int left=i,right=len-1;
while(left<=right)
{
int middle=(left+right)/2;
if(OK(i,middle-i+1))
left=middle+1;
else
right=middle-1;
}
num[i]=right-i+1;
}
void makehash()
{
for(int i=len-1;i>=0;i--)
{
has[i]=(has[i+1]*hashseed+s[i])%INF;
}
num[0]=len;
for(int i=1;i<len;i++)
{
getnum(i);
}
}
int main()
{
init();
while(scanf("%s",s)==1)
{
memset(has,0,sizeof has);
len=strlen(s);
makehash();
for(int i=len-1;i>=0;i--)
num[i]+=num[i+1];
LL ans=0;
for(int i=0;i<len;i++)
ans=(ans+getans(num[i]))%INF;
cout<<ans<<'\n';
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

最新文章

  1. component
  2. coffeeScript学习01
  3. 运行Maven是报错:No goals have been specified for this build
  4. Qt中QObject中的parent参数
  5. android 下载图片出现SkImageDecoder::Factory returned null,BitmapFactory.Options压缩
  6. 测试HAPROXY的文件分流办法
  7. Thinkphp3.2.2的上传问题
  8. poj 2749 Building roads (二分+拆点+2-sat)
  9. Splay POJ3468(老题新做)
  10. JVM性能监控与优化笔记(CPU)
  11. hdu3689(kmp+dp)
  12. 福州大学W班-需求分析评分排名
  13. token登录
  14. 常见MQTT服务器搭建[转载]
  15. gpu相关
  16. idea使用svn or git
  17. GetSystemInfo()
  18. GeForce GTX 1080 ti安装记录
  19. 开源的.NET任务调度框架-HangFire
  20. MyEclipse持续性开发教程:用JPA和Spring管理数据(二)

热门文章

  1. [React Intl] Format Numbers with Separators and Currency Symbols using react-intl FormattedNumber
  2. SpringMVC学习记录(五)--表单标签
  3. 关于C语言的书
  4. POJ 1364 King (UVA 515) 差分约束
  5. Android自定义组件系列【8】——遮罩文字动画
  6. 【23.48%】【codeforces 723C】Polycarp at the Radio
  7. js进阶 11-15 jquery过滤方法有哪些
  8. 栈溢出笔记1.9 认识SEH
  9. 【poj2528】Mayor's posters
  10. Android自定义控件View(二)继承控件