Codeforces Round #246 (Div. 2)——D题
KMP算法,没写出来,完全不理解NEXT数组。现在理解了很多
答案都在程序中
,不过这个思想真的很神奇,
还有毛语不好,一直没看懂题目,现在懂了,
大概是:S中前缀等于后缀,求其长度,和其在S中出现了几次,
KMP可以直接求出各个长度,但是求次数真的真的很神奇:
/*
CJT:第一份KMP算法,呜呜
我的理解:先求出next数组,next 数组的含义是:可以跳过的
个数,也是前缀的数
先求出tot,答案数,
然后求数组中有多少个可以substring
因为nexts是关于求对称的个数,所以
可以用来后面的求个数
*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
string s;
int vis[200000],tot;
int ans[200000],next[200000];
void kmp()
{
int k=-1,i=0;
next[0]=-1;
while (i<s.size())
{
if (k==-1||s[i]==s[k])
{
++k,++i;
next[i]=k;
}
else k=next[k];
}
}
int main()
{
cin>>s;
kmp();
int l=s.size();
int id=l;
while (id)
{
++tot;
vis[id]=1;
id=next[id];
}
for (int i=1;i<=l;i++) ans[i]=1;
for (int i=l;i>=1;i--)
ans[next[i]]+=ans[i];//这里很难写
cout<<tot<<endl;
for (int i=1;i<=l;i++)
if (vis[i]) cout<<i<<" "<<ans[i]<<endl;
return 0;
}
我的理解:先求出next数组,next 数组的含义是:可以跳过的
个数,也是前缀的数
先求出tot,答案数,
然后求数组中有多少个可以substring
因为nexts是关于求对称的个数,所以
可以用来后面的求个数
*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
string s;
int vis[200000],tot;
int ans[200000],next[200000];
void kmp()
{
int k=-1,i=0;
next[0]=-1;
while (i<s.size())
{
if (k==-1||s[i]==s[k])
{
++k,++i;
next[i]=k;
}
else k=next[k];
}
}
int main()
{
cin>>s;
kmp();
int l=s.size();
int id=l;
while (id)
{
++tot;
vis[id]=1;
id=next[id];
}
for (int i=1;i<=l;i++) ans[i]=1;
for (int i=l;i>=1;i--)
ans[next[i]]+=ans[i];//这里很难写
cout<<tot<<endl;
for (int i=1;i<=l;i++)
if (vis[i]) cout<<i<<" "<<ans[i]<<endl;
return 0;
}
随性Code