【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 }
3473: 字符串
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 121 Solved: 53
[Submit][Status][Discuss]
Description
给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串?
Input
第一行两个整数n,k。
接下来n行每行一个字符串。
Output
一行n个整数,第i个整数表示第i个字符串的答案。
Sample Input
3 1
abc
a
ab
abc
a
ab
Sample Output
6 1 3
HINT
对于 100% 的数据,1<=n,k<=10^5,所有字符串总长不超过10^5,字符串只包含小写字母。