• LOJ6070 基因 分块+回文自动机


    这个在翁文涛的论文里有讲到

    大概的就是一个子串的回文自动机是原串回文自动机的子图
    于是每隔(sqrt n)重新跑一个((k imes sqrt n,n))的回文自动机 记录回文串个数和位置 并且分别维护后缀的(fail)和前缀的(fail)

    每次询问((l,r))只需要把((k imessqrt n,r))的答案直接加上 再暴力添加((l,(k imessqrt n)-1))这一段就可以得到(ans)

    只理解了大概 只能以后遇到题再加强了

    (update:)新写了一篇(BZOJ5384)的博客,但是用那一题的方法加上主席树可以做到更优的复杂度

    #include<bits/stdc++.h>
    using namespace std;
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    #define pa pair<int,int>
    #define mod 1000000007
    #define ll long long
    #define mk make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define cl(x) memset(x,0,sizeof x)
    #ifdef Devil_Gary
    #define bug(x) cout<<(#x)<<" "<<(x)<<endl
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #else
    #define bug(x)
    #define debug(...)
    #endif
    const int INF = 0x7fffffff;
    const int N=1e5+5;
    const int M=355;
    /*
    char *TT,*mo,but[(1<<15)+2];
    #define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
    inline int read(){
        int x=0,rev=0,ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return rev?-x:x;
    }
    int type,n,S,T,Q,a[N],Ans,id=1;
    int ans[M][N],p[M][N],pos[M][N];
    int pb,pf,c[N][26],qf[N][26],f[N],len[N],vis[N];
    char s[N];
    void exback(int l,int i){
    	int x=a[i];
    	if(i-len[pb]-1<l||a[i-len[pb]-1]!=x) pb=qf[pb][x];
    	if(!c[pb][x]){
    		len[++id]=len[pb]+2;
    		int k=f[pb];
    		if(a[i-len[k]-1]!=x) k=qf[k][x]; k=c[k][x];
    		memcpy(qf[id],qf[k],sizeof qf[k]);
    		qf[id][a[i-len[k]]]=k,f[id]=k,c[pb][x]=id;
    	}
    	pb=c[pb][x];
    	if(len[pb]==i-l+1) pf=pb;
    }
    void exfront(int i,int r){
    	int x=a[i];
    	if(i+len[pf]+1>r||a[i+len[pf]+1]!=x) pf=qf[pf][x];
    	if(!c[pf][x]){
    		len[++id]=len[pf]+2;
    		int k=f[pf];
    		if(a[i+len[k]+1]!=x) k=qf[k][x];k=c[k][x];
    		memcpy(qf[id],qf[k],sizeof qf[k]);
    		qf[id][a[i+len[k]]]=k,f[id]=k,c[pf][x]=id;
    	}
    	pf=c[pf][x];
    	if(len[pf]==r-i+1) pb=pf; 
    }
    int calc(int x){
    	return (x-1)/S+1;
    }
    int main(){
    #ifdef Devil_Gary
    	freopen("in.txt","r",stdin);
    #endif
    	type=read(),n=read(),Q=read(),S=sqrt(n),scanf("%s",s+1);
    	for(int i=1;i<=n;i++) a[i]=s[i]-'a';
    	f[0]=f[1]=1,len[1]=-1;
    	for(int i=0;i<26;i++) qf[0][i]=1;
    	memset(pos,127/3,sizeof pos);
    	for(int L=1,i=1;L<=n;L+=S,i++){
    		pb=pf=0,++T;
    		for(int j=L;j<=n;j++){
    			exback(L,j);
    			ans[i][j]=ans[i][j-1],p[i][j]=pf;
    			if(vis[pb]<T) vis[pb]=T,pos[i][pb]=j,ans[i][j]++;
    		}
    	}
    	while(Q--){
    		int L=read(),R=read();
    		if(type) L^=Ans,R^=Ans;Ans=0;
    		if(calc(L)==calc(R)){
    			pb=0,++T;
    			for(int j=L;j<=R;j++){
    				exback(L,j);
    				if(vis[pb]<T) ++Ans,vis[pb]=T;
    			}
    		}
    		else{
    			int i=calc(L);Ans=ans[i+1][R];
    			pf=p[i+1][R],++T;
    			for(int j=i*S;j>=L;j--){
    				exfront(j,R);
    				if(vis[pf]<T) vis[pf]=T,Ans+=pos[i+1][pf]>R;
    			}
    		}
    		printf("%d
    ",Ans);
    	}
    }
    
    
    
  • 相关阅读:
    明暗文切换(密码输入框)遇到的坑
    iOS11适配tableView顶部空白
    macOS升级到high Sierra后, Cocoapods不能使用解决办法
    Xcode插件失效以后的处理方法
    iOS正确使用const,static,extern
    centos7安装magento随记 这就是个坑,果断放弃
    关于迅雷试用短租日租会员的一些渠道收集
    json中含有Unicode的处理办法 C#
    c#中奖算法的实现
    2016年最新mac下vscode配置golang开发环境支持debug
  • 原文地址:https://www.cnblogs.com/devil-gary/p/9213689.html
Copyright © 2020-2023  润新知