题目概述
给出
n
个模板串,现在要求一个最长的串,使得该串中所有长度为
解题报告
其实不难吧……但是太弱了就没想出来。
对于每个模板,相邻两个长度为
K−1
(不是
K
,因为两个
示例程序
自然溢出+map……
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
typedef long long LL;typedef unsigned long long ULL;
const int maxl=1000000,Base=23333;
int n,K,tot;ULL Ha[maxl+5],pw[maxl+5];char s[maxl+5];
int E,lnk[maxl+5],son[maxl+5],nxt[maxl+5];
int f[maxl+5],que[maxl+5],dis[maxl+5];
map<ULL,int> ID;
#define Eoln(x) ((x)==10||(x)==13||(x)==EOF)
inline char readc()
{
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF;return *l++;
}
inline int readi(int &x)
{
int tot=0,f=1;char ch=readc(),lst='+';
while ('9'<ch||ch<'0') {if (ch==EOF) return EOF;lst=ch;ch=readc();}
if (lst=='-') f=-f;
while ('0'<=ch&&ch<='9') tot=(tot<<1)+(tot<<3)+ch-48,ch=readc();
return x=tot*f,Eoln(ch);
}
inline int reads(char *s)
{
int len=0;char ch=readc();while ('z'<ch||ch<'a') ch=readc();
s[++len]=ch;while ('a'<=s[len]&&s[len]<='z') s[++len]=readc();
s[len--]=0;return len;
}
inline void Add(int x,int y) {son[++E]=y;nxt[E]=lnk[x];lnk[x]=E;}
#define Hash(L,R) (Ha[L]-Ha[(R)+1]*pw[(R)-(L)+1])
int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
pw[0]=1;for (int i=1;i<=maxl;i++) pw[i]=pw[i-1]*Base;
while (~readi(n))
{
readi(K);K--;E=0;memset(lnk,0,sizeof(lnk));memset(f,0,sizeof(f));tot=0;ID.clear();
for (int i=1;i<=n;i++)
{
int len=reads(s);if (len<=K) continue;Ha[len+1]=0;
for (int j=len;j>=1;j--) Ha[j]=Ha[j+1]*Base+s[j];
for (int j=K+1;j<=len;j++)
{
ULL lst=Hash(j-K,j-1),now=Hash(j-K+1,j);
if (!ID.count(lst)) ID[lst]=++tot;if (!ID.count(now)) ID[now]=++tot;
Add(ID[lst],ID[now]);f[ID[now]]++;
}
}
int Head=0,Tail=0;for (int i=1;i<=tot;i++) if (!f[i]) que[++Tail]=i,dis[Tail]=0;
while (Head!=Tail)
for (int j=lnk[que[++Head]];j;j=nxt[j])
if (!(--f[son[j]])) que[++Tail]=son[j],dis[Tail]=dis[Head]+1;
if (Tail!=tot) printf("INF\n"); else printf("%d\n",K+dis[Tail]);
}
return 0;
}