【BZOJ】【3473】字符串

后缀数组


  Orz zyf 神题不会做啊,先坑着吧……sigh

 1 //BZOJ 3473
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 typedef long long LL;
14 inline int getint(){
15     int r=1,v=0; char ch=getchar();
16     for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
17     for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
18     return r*v;
19 }
20 const int N=1e5+10,INF=~0u>>2;
21 /*******************template********************/
22 int sa[N],rank[N],height[N],belong[N],ans[N];
23 int wa[N],wb[N],c[N],n,q,a[N];
24 bool cmp(int *r,int a,int b,int l){
25     return r[a]==r[b] && r[a+l]==r[b+l];
26 }
27 void DA(int *s,int *sa,int n,int m){
28     int i,j,p,*x=wa,*y=wb;
29     rep(i,m) c[i]=0;
30     rep(i,n) c[x[i]=s[i]]++;
31     F(i,1,m-1) c[i]+=c[i-1];
32     D(i,n-1,0) sa[--c[x[i]]]=i;
33     for(j=1,p=0;p<n;j<<=1,m=p){
34         for(p=0,i=n-j;i<n;i++) y[p++]=i;
35         rep(i,n) if (sa[i]>=j) y[p++]=sa[i]-j;
36 
37         rep(i,m) c[i]=0;
38         rep(i,n) c[x[y[i]]]++;
39         F(i,1,m-1) c[i]+=c[i-1];
40         D(i,n-1,0) sa[--c[x[y[i]]]]=y[i];
41         swap(x,y); p=1; x[sa[0]]=0;
42         F(i,1,n-1) x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p-1 : p++;
43     }
44 }
45 void calheight(int *s,int *sa,int n){
46     int k=0;
47     F(i,1,n) rank[sa[i]]=i;
48     rep(i,n){
49         if (k) k--;
50         int j=sa[rank[i]-1];
51         while(s[i+k]==s[j+k]) k++;
52         height[rank[i]]=k;
53     }
54 }
55 char s[N];
56 int main(){
57 #ifndef ONLINE_JUDGE
58     freopen("3473.in","r",stdin);
59     freopen("3473.out","w",stdout);
60 #endif
61     n=getint(); q=getint()-1;
62     int l=0;
63     F(i,1,n){
64         scanf("%s",s+l);
65         l=strlen(s);
66         s[l++]='a'-5;
67     }
68     rep(i,l) a[i]=s[i]-'a'+10;
69     l--;
70     DA(a,sa,l+1,41);
71     calheight(a,sa,l);
72     ST();
73     int tmp=1;
74     rep(i,l){
75         if (s[i]<10){tmp++;continue;}
76         belong[rank[i]]=tmp;
77     }
78     int t=1,k=0;
79     F(i,1,l) if(belong[i]){
80         if (!cnt[belong[i]]) k++;
81         cnt[belong[i]]++;
82         if (k<=q){
83             for(;k-(cnt[belong[t]]==1)>=q; k-=(cnt[belong[t]]==1), --cnt[belong[t++]]);
84             rec[i]=t;
85         }
86     }
87     F(i,1,n){
88         LL ans=0; int k=0;
89         F(j,
90     return 0;
91 }
View Code

3473: 字符串

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 121  Solved: 53
[Submit][Status][Discuss]

Description

给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串?

Input

第一行两个整数nk
接下来n行每行一个字符串。

Output

一行n个整数,第i个整数表示第i个字符串的答案。

Sample Input

3 1
abc
a
ab

Sample Output

6 1 3

HINT



对于 100% 的数据,1<=n,k<=10^5,所有字符串总长不超过10^5,字符串只包含小写字母。

Source

[Submit][Status][Discuss]
posted @ 2015-04-08 09:43  Tunix  阅读(416)  评论(0编辑  收藏  举报