hdu 4622(后缀自动机|后缀数组)

//昨天晚上一直用后缀数组来写,怎么写都超时(后来在网上看到也有用后缀数组过的,然来是自己昨晚sb,用把l,r区间的rank数组排序来使l,r区间内的rank有序,其实直接按rank,O(n)遍历就可以做到),

//今天看了多校3的官方解题,可以用后缀自动机;

//今天上午就去学习了后缀自动机(以前没有主动去学后缀自动机,总想后缀自动机能解的,后缀数组都能解,这次顺便学习一下);

//官方解题说这题后缀自动机可以O(n^2)+O(1),可是我写的后缀自动机时间复杂度还是O(n*q),因为每次计算字串的个数的还是把所有的step遍历了的一遍,

//但是没有重新建树,建树的常数小了一些;

//思考:(不知道计算字串的个数的时候可不可以利用以前的信息,也就是F数组的修改更新可不可以记录下来,去想想,继续学习后缀自动机);

//ac 代码如下:


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define N 2010

int F[N*2],ant,last,ch[N*2][26],step[N*2];
void init(){
    last=ant=1;
    memset(F,0,sizeof(F));
    memset(ch,0,sizeof(ch));
    memset(step,0,sizeof(step));
}
void ins(int x){
    int t=++ant,pa=last;
    step[t]=step[last]+1;last=t;
    for(;pa&&!ch[pa][x];pa=F[pa]) ch[pa][x]=t;
    if(pa==0) F[t]=1;
    else if(step[pa]+1==step[ch[pa][x]]) F[t]=ch[pa][x];
    else {
        int nq=++ant,q=ch[pa][x];
        memcpy(ch[nq],ch[q],sizeof(ch[nq]));
        step[nq]=step[pa]+1;F[nq]=F[q];F[q]=F[t]=nq;
        for(;pa&&ch[pa][x]==q;pa=F[pa]) ch[pa][x]=nq;
    }
}
//以上为后缀自动机的部分

char s[N];
int ans[10100];

vector > Q[N];

void run(int p){
    int i,t,j,tt;
    init();
    sort(Q[p].begin(),Q[p].end());
    for(i=0,t=p-1;i<(int)Q[p].size();i++){
        if(i&&Q[p][i].first==t){
            ans[Q[p][i].second]=tt; continue;
        }
        while(t0;j--) tt+=step[j]-step[F[j]];
        ans[Q[p][i].second]=tt;
    }
}

int main(){
    int cas,n,i,a,b,m;
    scanf("%d",&cas);
    while(cas--){
        scanf("%s",s);m=strlen(s);
        for(i=1;i<=m;i++) Q[i].clear();
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d%d",&a,&b);
            Q[a].push_back(make_pair(b,i));
        }
        for(i=1;i<=m;i++) if(Q[i].size()) run(i);
        for(i=1;i<=n;i++) printf("%d\n",ans[i]);
    }
	return 0;
}


//后缀数组修改后ac的代码

#include
#include
#include
#include

using namespace std;

const int maxn = 2100;
char s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn];
void build_sa(int n,int m){
	int i,k,*x=t,*y=t2,p;
	//基数排序
	for(i=0;i=0;i--) sa[--c[x[i]]]=i;
	for(k=1;k=k) y[p++]=sa[i]-k;
		//基数排序第一关键字
		for(i=0;i=0;i--) sa[--c[x[y[i]]]]=y[i];
		//根据sa和y数组计算新的x数组
		swap(x,y);
		p=1; x[sa[0]]=0;
		for(i=1;i=n)break;
		m=p;
	}
}
int rank[maxn],height[maxn];
void getHeight(int n)
{
	int i,j,k=0;
	for(i=1;i<=n;i++) rank[sa[i]] = i;
	for(i=0;in) break;
    }
    ans+=A[1].d;
    int b=1;
    for(i=2;i<=n;i++){
        ans+=A[i].d-min(A[i].d,min(A[b].d,dp[A[b].k][A[i].k]));
        if(A[b].d>A[i].d&&dp[A[b].k][A[i].k]>=A[i].d); else b=i;
    }
    return ans;
}
int main(){
    int cas,n,a,b;
    scanf("%d",&cas);
    while(cas--){
        scanf("%s",s);
        M=strlen(s);
        build_sa(M+1,255);
        getHeight(M);brute_rmp(M);
        scanf("%d",&n);
        while(n--){
            scanf("%d%d",&a,&b);
            printf("%d\n",run(a-1,b-1));
        }
    }
	return 0;
}


你可能感兴趣的:(数据结构,一些模板)