【JZOJ4964】【GDKOI2017模拟1.21】Rhyme
2017-01-21 20:13
330 查看
Description
由于多次交换邮票没有满足所有人的需求,小Z被赶出了集邮部。无处可去的小Z决定加入音乐部,为了让音乐部的人注意到自己的才华,小Z想写一首曲子。为了让自己的曲子更好听,小Z找到了一些好听曲子作为模板。曲谱可以表示成只包含小写字母的字符串,小Z希望自己最终的曲谱中任意一个长度为K的子串都是一个模板的子串。现在小Z想知道自己的曲谱最长可以是多长,如果可以无限长的话请输出INF。Data Constraint
对于30%的数据:K=2。对于70%的数据:每组数据字符串总长不超过1000。
对于100%的数据:每组数据字符串总长不超过100000,1≤K≤100000。每个测试点数据不超过10组。dbhfdf
Solution
这道题其实很好想,难的是优化。我们将相邻的两个长度为k-1的子串连一条长度为1的边,判断一下有没有环,没有就输出最长路。怎么做呢?考场上我想出了用spfa判环和最长路。但这显然是不行的!我们考虑换一种算法。
我们想到一个同样可以判环的工具:拓扑排序,而且这是O(N)的。同时,由于所有边的权值均为1,最后使点x的入度为0的点y一定是到达x的最远点。所以用拓扑排序一样能求出最长路。
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long #define ul unsigned long long using namespace std; const int maxn=4e5+7,maxn1=1e5+5; ul first[maxn],last[2*maxn],next[2*maxn]; ul d[maxn]; ul v[maxn],fa[maxn],bz[maxn]; char s[maxn1]; ul h[maxn],a[maxn1],er[maxn1]; ul n,m,i,t,j,k,l,x,y,z,num,bz1,ans; void lian(ul x,ul y){ last[++num]=y;next[num]=first[x];first[x]=num; } ul hash(ul x){ ul t=(x%maxn+maxn)%maxn; while (h[t] && h[t]!=x) t=(t+1)%maxn; h[t]=x;return t; } void spfa(){ int i,j=0,x,t; for (i=1;i<=v[0];i++) if (!fa[v[i]] && !bz[v[i]]) v[++j]=v[i],d[v[i]]=0,bz[v[i]]=1; i=0; while (i<j){ x=v[++i]; for (t=first[x];t;t=next[t]){ fa[last[t]]--; if (!fa[last[t]]) d[last[t]]=d[x]+1,v[++j]=last[t]; } } } int main(){ freopen("data.in","r",stdin);//freopen("rhyme.out","w",stdout); er[0]=1; for (i=1;i<maxn1;i++) er[i]=er[i-1]*27; while (scanf("%u",&n)!=EOF){ scanf("%u\n",&m); memset(h,0,sizeof(h));memset(bz,0,sizeof(bz)); memset(first,0,sizeof(first));memset(fa,0,sizeof(fa)); num=0;v[0]=0;ans=0; for (i=1;i<=n;i++){ scanf("%s\n",s+1);l=strlen(s+1); for (j=1;j<=l;j++) a[j]=a[j-1]*er[1]+s[j]-96; for (j=m;j<=l;j++){ y=a[j]-a[j-m+1]*er[m-1]; t=hash(y); y=a[j-1]-a[j-m]*er[m-1]; k=hash(y);lian(k,t);fa[t]++; if (j==m) v[++v[0]]=k; } } bz1=0; spfa(); for (i=0;i<maxn;i++){ if (h[i]) ans=max(ans,d[i]); if (h[i] && fa[i]) break; } if (bz1|| i!=maxn || m<=1) printf("INF\n"); else ans+=m-1,printf("%u\n",ans); } }
相关文章推荐
- 【JZOJ4964】【GDKOI2017模拟1.21】Rhyme
- 【GDKOI2017模拟1.21】Rhyme
- 【JZOJ4965】【GDKOI2017模拟1.21】Equation
- 【GDKOI2017模拟1.21】Rhyme
- 【JZOJ4963】【GDKOI2017模拟1.21】Book
- 【JZOJ4937】【GDKOI2017模拟1.12】与运算
- 【GDKOI2017模拟1.21】Equation
- 【JZOJ 4964】 Rhyme
- 【GDKOI2017模拟1.21】Equation
- Book 【GDKOI2017模拟1.21】
- [JZOJ4964]Rhyme
- 【jzoj4964】【Rhyme】【字符串哈希】【拓扑排序】
- JZOJ 4937【GDKOI2017模拟1.12】与运算
- 【GDKOI2017模拟1.21】Book
- JZOJ 4937 【GDKOI2017模拟1.12】与运算
- JZOJ5603. 【NOI2018模拟3.27】Xjz
- 【jzoj4764】【Brothers】【模拟】
- 【JZOJ4805】【NOIP2016提高A组模拟9.28】跟踪
- jzoj P1507【普及模拟】数列
- JZOJ 4819 【NOIP2016提高A组模拟10.15】算循环