首页 > 代码库 > Obsessive String
Obsessive String
Codeforces Round #282 (Div. 1) B. Obsessive String
题目:链接
解题思路:
- 先用kmp找到所有的匹配点,时间复杂度O(n)
- 用dp[i]表示i是bk(题中的)时,字符串前i个字符的子串中的满足条件的总数
- 定义dp2[i]是前i个dp[i]的和,dp3[i]是前i个dp2[i]的和,m是匹配串的长度。
- 转移:当i不是匹配的结尾点时,dp[i]=dp[i-1],反之,dp[i]=dp3[i]+i-m+1;
- 当i不是匹配的结尾点时,只要把bk从i-1点变到i点,故数量不变,dp[i]=dp[i-1]。
- 而当i是匹配的结尾点时,考虑ak(题中)可以取1,2,..,i-m+1(index从1开始)
- 故当k=1时,有i+m-1个(当时就由于没考虑到k=1的情况要单独算,一直过不了样例)
- 当k大于1时,当ak取j(1<=j<=i-m+1)时,bk-1可以取1,2,...,j-1,故有dp2[j-1]
- 而由ak取值,故有dp3[i-m]个,故dp[i]=dp3[i]+i-m+1
- 最后的结果就是dp2[n-1],n为字符串长度。
- 注意取模
- 同时解题思路index是从1开始,我程序中index从0开始
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int maxn=100010; 7 const int mod=1e9+7; 8 char s[maxn]; 9 char t[maxn];10 int f[maxn];11 int dp[maxn];12 int q[maxn];13 int dp2[maxn];14 int dp3[maxn];15 void getFail(char *P, int *f)16 {17 int m=strlen(P);18 f[0]=0;19 f[1]=0;20 for(int i=1;i<m;i++)21 {22 int j=f[i];23 while(j&&P[i]!=P[j])24 {25 j=f[j];26 }27 f[i+1]=P[i]==P[j]?j+1:0;28 }29 }30 void find(char *T,char *P,int *f)31 {32 int n=strlen(T);33 int m=strlen(P);34 getFail(P,f);35 int j=0;36 for(int i=0;i<n;i++)37 {38 while(j&&P[j]!=T[i])39 {40 j=f[j];41 }42 if(P[j]==T[i])43 {44 j++;45 }46 if(j==m)47 {48 q[i]=1;49 }50 }51 }52 53 54 int main()55 {56 while(scanf("%s%s",s,t)!=EOF)57 {58 int i;59 memset(q,0,sizeof(q));60 find(s,t,f);61 int n=strlen(s);62 int m=strlen(t);63 if(q[0])64 {65 dp[0]=1;66 dp2[0]=1;67 dp3[0]=1;68 }69 else70 {71 dp[0]=0;72 dp2[0]=0;73 dp3[0]=0;74 }75 for(i=1;i<=n;i++)76 {77 if(q[i]==0)78 {79 dp[i]=dp[i-1];80 }81 else82 {83 dp[i]=(dp3[i-m]+i-m+2)%mod;84 }85 dp2[i]=(dp[i]+dp2[i-1])%mod;86 dp3[i]=(dp2[i]+dp3[i-1])%mod;87 }88 printf("%d\n",dp2[n-1]);89 }90 91 92 93 return 0;94 }
AC如下:
Obsessive String
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。