3277: 串
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 811 Solved: 329
[Submit][Status][Discuss]
Description
字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中
至少k个字符串的子串(注意包括本身)。
Input
第一行两个整数n,k。
接下来n行每行一个字符串。
n,k,l<=100000
Output
输出一行n个整数,第i个整数表示第i个字符串的答案。
Sample Input
3 1
abc
a
ab
Sample Output
6 1 3
HINT
Source
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdio> 7 #define maxn 200005 8 using namespace std; 9 int n,k; 10 long long c[maxn]; 11 long long ans[maxn]; 12 struct data { 13 long long son[maxn][26],link[maxn],step[maxn],last,cnt,t[maxn],size[maxn],tp[maxn]; 14 data() {last=cnt=1;} 15 void extend(int x,int id) { 16 int p=last,np=last=++cnt;step[np]=step[p]+1;t[np]=id; 17 while(p&&!son[p][x]) son[p][x]=np,p=link[p]; 18 if(!p) link[np]=1; 19 else { 20 int q=son[p][x]; 21 if(step[q]==step[p]+1) link[np]=q; 22 else { 23 int nq=++cnt; 24 memcpy(son[nq],son[q],sizeof(son[q])); 25 step[nq]=step[p]+1; 26 link[nq]=link[q];link[np]=link[q]=nq;size[nq]=size[q];tp[nq]=tp[q]; 27 while(p&&son[p][x]==q) son[p][x]=nq,p=link[p]; 28 } 29 } 30 for(int i=np;i&&tp[i]!=id;i=link[i]) size[i]++,tp[i]=id; 31 } 32 }sam; 33 int head[maxn],sum; 34 struct edge { 35 int to,next; 36 }e[maxn]; 37 void add(int u,int v) {e[sum].to=v;e[sum].next=head[u];head[u]=sum++;} 38 char s[maxn]; 39 void dfs(int x) { 40 c[x]+=c[sam.link[x]];ans[sam.t[x]]+=c[x]; 41 for(int i=head[x];i>=0;i=e[i].next) dfs(e[i].to); 42 } 43 int main() { 44 memset(head,-1,sizeof(head)); 45 scanf("%d%d",&n,&k); 46 for(int i=1;i<=n;i++) { 47 scanf("%s",s+1); 48 int len=strlen(s+1);sam.last=1; 49 for(int j=1;j<=len;j++) sam.extend(s[j]-‘a‘,i); 50 } 51 for(int i=2;i<=sam.cnt;i++) { 52 add(sam.link[i],i); 53 if(sam.size[i]>=k) c[i]=sam.step[i]-sam.step[sam.link[i]]; 54 } 55 dfs(1); 56 for(int i=1;i<=n;i++) printf("%lld ",ans[i]); 57 } 58 /* 59 3 2 60 abaac 61 bba 62 bbacb 63 */
原文地址:https://www.cnblogs.com/wls001/p/8474695.html
时间: 2024-10-11 08:33:42