zoukankan      html  css  js  c++  java
  • BZOJ5084: hashit

    BZOJ5084: hashit

    https://lydsy.com/JudgeOnline/problem.php?id=5084

    分析:

    • (trie)建立广义后缀自动机,由于是(trie),不会有多余结点(lenx==lenfa)
    • 令后缀自动机结点权值为(len_x-len _ {fa_x})
    • 每次询问时答案就等于所有结点到根的树链的并的权值和。
    • 每次是插入一个点,删除一个点,用(set)动态维护即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <set>
    using namespace std;
    typedef long long ll;
    #define N 100050
    #define db(x) cerr<<#x<<" = "<<x<<endl
    char opt[N];
    int n;
    struct Trie {
    	int ch[N][26],cnt,fa[N];
    	void init() {cnt=1;}
    	void Wk() {
    		init();
    		int i,p=1;
    		for(i=1;i<=n;i++) {
    			if(opt[i]=='-') {
    				p=fa[p];
    			}else {
    				int &q=ch[p][opt[i]-'a'];
    				if(!q) q=++cnt,fa[q]=p;
    				p=q;
    			}
    		}
    	}
    }t1;
    struct Sam {
    	#undef N 
    	#define N 200050
    	int ch[N][26],fa[N],len[N],cnt,Q[N],Lst[N];
    	int ke[N],ro[N],f[20][N],Lg[N],dep[N],w[N];
    	ll dis[N];
    	int head[N],to[N],nxt[N],tot,dfn[N];
    	inline void add(int u,int v) {
    		to[++tot]=v; nxt[tot]=head[u]; head[u]=tot;
    	}
    	void dfs(int x) {
    		int i; dfn[x]=++dfn[0];
    		for(i=head[x];i;i=nxt[i]) {
    			dep[to[i]]=dep[x]+1; 
    			w[to[i]]=len[to[i]]-len[x];
    			dis[to[i]]=dis[x]+w[to[i]];
    			dfs(to[i]);
    		}
    	}
    	void init() {cnt=1;}
    	int insert(int x,int lst) {
    		int p=lst,np=++cnt,q,nq;
    		len[np]=len[p]+1; lst=np;
    		for(;p&&!ch[p][x];p=fa[p]) ch[p][x]=np;
    		if(!p) fa[np]=1;
    		else {
    			q=ch[p][x];
    			if(len[q]==len[p]+1) fa[np]=q;
    			else {
    				nq=++cnt; 
    				len[nq]=len[p]+1; fa[nq]=fa[q]; memcpy(ch[nq],ch[q],sizeof(ch[q]));
    				fa[np]=fa[q]=nq;
    				for(;p&&ch[p][x]==q;p=fa[p]) ch[p][x]=nq;
    			}
    		}return lst;
    	}
    	int lca(int x,int y) {
    		int i;
    		if(dep[x]<dep[y]) swap(x,y);
    		for(i=Lg[dep[x]];i>=0;i--) {
    			if(dep[f[i][x]]>=dep[y]) x=f[i][x];
    		}if(x==y) return x;
    		for(i=Lg[dep[x]];i>=0;i--) {
    			if(f[i][x]!=f[i][y]) x=f[i][x],y=f[i][y];
    		}return f[0][x];
    	}
    	struct A {
    		int x,v;
    		bool operator < (const A &u) const {return v<u.v;}
    	};
    	set<A>S;
    	set<A>::iterator it;
    	ll nowans;
    	void fadd(int p) {
    		A t=(A){p,dfn[p]};
    		nowans+=dis[p];
    		it=S.upper_bound(t);
    		int x=0,y=0;
    		if(it!=S.end()) {
    			y=it->x;
    		}
    		if(it!=S.begin()) {
    			it--;
    			x=it->x;
    		}
    		if(x) nowans-=dis[lca(x,p)];
    		if(y) nowans-=dis[lca(y,p)];
    		if(x&&y) nowans+=dis[lca(x,y)];
    		S.insert(t);
    	}
    	void fdel(int p) {
    		A t=(A){p,dfn[p]};
    		S.erase(t);
    		nowans-=dis[p];
    		it=S.upper_bound(t);
    		int x=0,y=0;
    		if(it!=S.end()) {
    			y=it->x;
    		}
    		if(it!=S.begin()) {
    			it--;
    			x=it->x;
    		}
    		if(x) nowans+=dis[lca(x,p)];
    		if(y) nowans+=dis[lca(y,p)];
    		if(x&&y) nowans-=dis[lca(x,y)];
    	}
    	void Wk() {
    		init();
    		int p,i,j;
    		int l=0,r=0;
    		Q[r++]=1; Lst[1]=1;
    		while(l<r) {
    			p=Q[l++];
    			for(i=0;i<26;i++) if(t1.ch[p][i]) {
    				int q=t1.ch[p][i];
    				Lst[q]=insert(i,Lst[p]);
    				Q[r++]=q;
    			}
    		}
    		Lg[0]=-1;
    		for(i=1;i<=cnt;i++) f[0][i]=fa[i],Lg[i]=Lg[i>>1]+1;
    		for(i=1;(1<<i)<=cnt;i++) {
    			for(j=1;j<=cnt;j++) f[i][j]=f[i-1][f[i-1][j]];
    		}
    		for(i=2;i<=cnt;i++) add(fa[i],i);
    		dfs(1);
    		p=1;
    		for(i=1;i<=n;i++) {
    			if(opt[i]=='-') {
    				fdel(Lst[p]);
    				p=t1.fa[p];
    				printf("%lld
    ",nowans);
    			}else {
    				p=t1.ch[p][opt[i]-'a'];
    				fadd(Lst[p]);
    				printf("%lld
    ",nowans);
    			}
    		}
    	}
    }t2;
    int main() {
    	scanf("%s",opt+1);
    	n=strlen(opt+1);
    	t1.Wk();
    	t2.Wk();
    }
    
  • 相关阅读:
    pip install uwsgi 报错 AttributeError: module 'os' has no attribute 'uname'
    npm安装vue
    Node.js安装及环境配置之Windows篇
    Centos7 安装nodejs
    Centos7 Jenkins 插件下载速度慢、安装失败
    Centos7 使用docker 安装redis
    Centos7 安装jdk
    supervisor配置文件详解
    MySQL5.7 group by新特性,报错1055
    配置python虚拟环境Virtualenv及pyenv
  • 原文地址:https://www.cnblogs.com/suika/p/10205835.html
Copyright © 2011-2022 走看看