国家队论文链接:链接:http://pan.baidu.com/s/1E1K4m 密码:cfog
(更新中)
/***********************************************************/
简单的说,后缀数组是“排第几的是谁?”,名次数组是“你排第几?”。
待排序的字符串放在r 数组中,从r[0]到r[n-1],长度为n,且最大值小
于m。为了函数操作的方便,约定除r[n-1]外所有的r[i]都大于0, r[n-1]=0。
函数结束后,结果放在sa 数组中,从sa[0]到sa[n-1]。
height 数组:定义height[i]=suffix(sa[i-1])和suffix(sa[i])的最长公
共前缀,也就是排名相邻的两个后缀的最长公共前缀。
/***********************************************************/
poj 1743 Musical Theme http://poj.org/problem?id=1743 不可重叠重复字串
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem:poj 1743 User: youmi Language: C++ Result: Accepted Time:219MS Memory:1384K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <ctime> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d ",a) #define ptlld(a) printf("%I64d ",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; const int maxn=20010; int wa[maxn],wb[maxn],wv[maxn],cnt[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[x[i]=r[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[wv[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rk[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return; } int r[maxn],sa[maxn]; int f[maxn]; int n; bool work(int temp) { int l=oo,r=-1; for(int i=2;i<=n;i++) { while(height[i]>=temp) { l=Min(l,Min(sa[i],sa[i-1])); r=Max(r,Max(sa[i],sa[i-1])); i++; } if(r-l>=temp) return true; else { l=oo,r=-1; } } return false; } int main() { //freopen("in.txt","r",stdin); while(~sc(n)&&n) { rep0(i,n) sc(f[i]); for(int i=0;i<n-1;i++) r[i]=f[i+1]-f[i]+88; n--; r[n]=0; /**< for(int i=0;i<=n;i++) printf("%d ",r[i]); cout<<endl; */ da(r,sa,n+1,200); calheight(r,sa,n); int l=0,r=n+1; int mid=0; int ans=0; while(l<=r) { mid=(l+r)>>1; if(work(mid)) { l=mid+1; ans=mid; } else r=mid-1; } if(ans>=4) { pt(ans+1); } else printf("0 "); } return 0; }
poj 3261 Milk Patterns http://poj.org/problem?id=3261 可重叠重复字串K次
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem:poj 3261 User: youmi Language: C++ Result: Accepted Time:32MS Memory:1480K ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <ctime> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d ",a) #define ptlld(a) printf("%I64d ",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; const int maxn=20010; int wa[maxn],wb[maxn],wv[maxn],cnt[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[x[i]=r[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[wv[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rk[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return; } int r[maxn],sa[maxn]; typedef struct { int v,p; }node; node ha[maxn]; bool small(const node a,const node b) { if(a.v==b.v) return a.p<b.p; return a.v<b.v; } int n,k; void to_one() { sort(ha,ha+n,small); int cnt=1; r[ha[0].p]=cnt; for(int i=1;i<n;i++) { if(ha[i].v!=ha[i-1].v) r[ha[i].p]=++cnt; else r[ha[i].p]=r[ha[i-1].p]; } } bool work(int temp) { int tot; for(int i=2;i<=n;i++) { tot=1; while(height[i]>=temp) { tot++; i++; } if(tot>=k) return true; } return false; } int main() { //freopen("in.txt","r",stdin); while(~sc2(n,k)) { rep0(i,n) { sc(ha[i].v); ha[i].p=i; } to_one(); r[n]=0; /**<for(int i=0;i<=n;i++) printf("%d ",r[i]); cout<<endl; */ da(r,sa,n+1,n+1); calheight(r,sa,n); int l=0,r=n+1; int mid=0; int ans=0; while(l<=r) { mid=(l+r)>>1; if(work(mid)) { l=mid+1; ans=mid; } else r=mid-1; } printf("%d ",ans); } return 0; }
ural 1297 回文串 http://acm.timus.ru/problem.aspx?space=1&num=1297
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem:ural 1297 User: youmi Language: C++ Result: Accepted Time:0.015 s Memory:568 KB ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d ",a) #define ptlld(a) printf("%I64d ",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; const int maxn=2010; int wa[maxn],wb[maxn],wv[maxn],cnt[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[x[i]=r[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[wv[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rk[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return; } int r[maxn],sa[maxn]; char s[maxn]; int n; int dp[maxn][15]; void test() { rep1(i,n) printf("%d ",dp[i][0]); cout<<endl; } void RMQ() { int k=(int)(log(n*1.0)/log(2.0)); for(int i=1;i<=n;i++) dp[i][0]=height[i]; for(int j=1;j<=k;j++) for(int i=1;i+(1<<j)<=n;i++) dp[i][j]=Min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } int lcp(int a,int b) { int l=rk[a],r=rk[b]; if(l>r) { int t=l; l=r; r=t; } l++; int k=(int )(log((r-l+1)*1.0)/log(2.0)); return Min(dp[l][k],dp[r-(1<<(k))+1][k]); } int main() { //freopen("in.txt","r",stdin); while(~scs(s)) { int len=strlen(s); n=0; for(int i=0;i<len;i++) r[n++]=s[i]; r[n++]=150; for(int i=0;i<len;i++) r[n++]=s[len-i-1]; r[n]=0; da(r,sa,n+1,160); calheight(r,sa,n); RMQ(); int pos=0,ans=1; int temp=0; int m=(len<<1); for(int i=0;i<len;i++) { temp=(lcp(i,m-i)<<1)-1; if(temp>ans) ans=temp,pos=i-(temp>>1); temp=lcp(i,(m-i+1))<<1; if(temp>ans) ans=temp,pos=i-(temp>>1); } for(int i=pos;i<pos+ans;i++) printf("%c",s[i]); cout<<endl; } return 0; }
poj 1226 Substrings http://poj.org/problem?id=1226
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem:poj 1226 User: youmi Language: C++ Result: Accepted Time:0MS Memory:1056K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d ",a) #define ptlld(a) printf("%I64d ",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; const int maxn=200100; int wa[maxn],wb[maxn],wv[maxn],cnt[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[x[i]=r[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[wv[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rk[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return; } char str[maxn]; int r[maxn],sa[maxn]; int who[maxn]; int vis[500]; int n,m; bool check(int temp) { int tot=0; zeros(vis); for(int i=2;i<=n;i++) { if(height[i]<temp) { tot=0; zeros(vis); } else { if(!vis[who[sa[i]]]) { vis[who[sa[i]]]=1; tot++; } if(!vis[who[sa[i-1]]]) { vis[who[sa[i-1]]]=1; tot++; } if(tot==m) return true; } } return false; } int main() { //freopen("in.txt","r",stdin); int T_T; scanf("%d",&T_T); for(int kase=1;kase<=T_T;kase++) { n=0; int sp=150; sc(m); rep1(i,m) { scs(str); int s1=strlen(str); for(int j=0;str[j];j++) { who[n]=i; r[n++]=str[j]; } who[n]=sp; r[n++]=sp++; for(int j=0;str[j];j++) { who[n]=i; r[n++]=str[s1-j-1]; } who[n]=sp; r[n++]=sp++; } r[n]=0; da(r,sa,n+1,sp); calheight(r,sa,n); int l=0,r=strlen(str); int mid=0,ans=0; while(l<=r) { mid=(l+r)>>1; if(check(mid)) { l=mid+1; ans=mid; } else r=mid-1; } pt(ans); } return 0; }
hdu 5769 substring
题意:给一个字符,下面一个串,问你下面的串可以组成的子串中有多少个包含这个字符的
思路:(自己没想出来,看别人博客会的,传送门,为了方便,我把思路也copy过来吧,写的挺好的)我们将sa[i]代表的串里有这个字符的全部标记起来,只有这些才会对我们的结果有贡献值,然后正常的我们算不重复子串的个数是len-sa[i]-height[i],但是现在有这样的情况,就是字符是c,而sa[i]是dddcddd,那么它能贡献的值就是len-max((sa[i]+height[i]),c的位置),因为若sa[i]+height[i]的值大于c的位置,这与正常的没有区别,但是若c的位置大于sa[i]+height[i],那么这个sa能贡献的就只有c位置和之后的串,所遇这里取个最大值就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/************************************************************** Problem:hdu 5769 Substring User: youmi Language: C++ Result: Accepted Time:140MS Memory:5160K ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <ctime> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d ",a) #define ptlld(a) printf("%I64d ",a) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; const int maxn=100100; int wa[maxn],wb[maxn],wv[maxn],cnt[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[x[i]=r[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) cnt[i]=0; for(i=0;i<n;i++) cnt[wv[i]]++; for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; for(i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int rk[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return; } int r[maxn],sa[maxn]; char s[maxn],ch[10]; int n; int op[maxn]; int main() { #ifndef ONLINE_JUDGE //freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE int T_T; sc(T_T); for(int kase=1;kase<=T_T;kase++) { printf("Case #%d: ",kase); scanf("%s%s",ch,s); n=strlen(s); int st=n; for(int i=n-1;i>=0;i--) { r[i]=s[i]; if(s[i]==ch[0]) st=i; op[i]=st; } r[n]=0; da(r,sa,n+1,128); calheight(r,sa,n); ll ans=0; for(int i=1;i<=n;i++) { ans+=n-Max(sa[i]+height[i],op[sa[i]]); } ptlld(ans); } return 0; }