• HDU 4117


    HDU - 4117

    构建AC自动机

    dp从每一个的子串上转移过来

    转移过程中不断匹配,然后统计\(fail\)树上前缀的最大值,这是一个动态的过程

    于是我们用树剖线段树动态维护

    
    const int N=2e4+10,SIZE=2.3e5+10;
    
    bool be;
    int n,m;
    string s[N];
    
    int End[N],val[N];
    int trie[SIZE][26],fail[SIZE],cnt;
    void clear(){
    	memset(trie,0,sizeof (int) * (cnt+1)*26);
    	cnt=0;
    }
    
    int Insert(string &s){
    	int p=0;
    	rep(i,0,s.size()-1) {
    		//if(!isalpha(s[i])) while(1);
    		int x=s[i]-'a';
    		if(!trie[p][x]) trie[p][x]=++cnt;
    		p=trie[p][x];
    	}
    	return p;
    }
    
    int sz[SIZE],son[SIZE],top[SIZE],fa[SIZE];
    
    struct Edge{
    	int to,nxt;
    }e[SIZE];
    int head[SIZE],ecnt;
    void AddEdge(int u,int v){
    	e[++ecnt].to=v;
    	e[ecnt].nxt=head[u];
    	head[u]=ecnt;
    }
    
    
    
    
    void dfs1(int u){
    	sz[u]=1,son[u]=-1;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(!v) continue;
    		fa[v]=u;
    		dfs1(v);
    		sz[u]+=sz[v];
    		if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;
    	}
    }
    
    int L[SIZE],R[SIZE],dfn;
    //id[SIZE];
    void dfs2(int u,int t){
    	top[u]=t;
    	L[u]=++dfn;
    	if(~son[u]) dfs2(son[u],t);
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(!v||v==son[u]) continue;
    		dfs2(v,v);
    	}
    	R[u]=dfn;
    }
    
    void chk(int &a,int b){ ((a<b)&&(a=b)); }
    struct SGT{
    	int sum[SIZE<<2];
    	void clear() { memset(sum,0,sizeof sum); }
    	void Upd(int p,int l,int r,int x,int y){
    		chk(sum[p],y);
    		if(l==r) return;
    		int mid=(l+r)>>1;
    		if(x<=mid) Upd(p<<1,l,mid,x,y);
    		else Upd(p<<1|1,mid+1,r,x,y);
    	}
    	int Que(int p,int l,int r,int ql,int qr){
    		if(l==ql&&r==qr) return sum[p];
    		int mid=(l+r)>>1;
    		if(qr<=mid) return Que(p<<1,l,mid,ql,qr);
    		else if(ql>mid) return Que(p<<1|1,mid+1,r,ql,qr);
    		else return max(Que(p<<1,l,mid,ql,mid),Que(p<<1|1,mid+1,r,mid+1,qr));
    	}
    }tr;
    
    
    void Build(){
    	static queue <int> que;
    	dfn=0;
    	memset(head,0,sizeof head);ecnt=0;
    	rep(i,0,25) if(trie[0][i]) {
    		que.push(trie[0][i]);
    		fail[trie[0][i]]=0;
    	}
    	while(!que.empty()){
    		int u=que.front(); que.pop();
    		AddEdge(fail[u],u);
    		rep(i,0,25) {
    			int &v=trie[u][i];
    			if(v) {
    				que.push(v);
    				fail[v]=trie[fail[u]][i];
    			} else v=trie[fail[u]][i];
    		}
    	}
    	fa[0]=-1,dfs1(0);dfs2(0,0);
    }
    
    
    bool ed;
    
    int main(){
    	//cout<<&ed-&be<<endl;
    	ios::sync_with_stdio(false);
    	int T; cin>>T;
    	rep(kase,1,T) {
    		clear();
    		tr.clear();
    		cin>>n;
    		rep(i,1,n) {
    			cin>>s[i]>>val[i];
    			End[i]=Insert(s[i]);
    		}
    		Build();
    		int ans=0;
    		rep(i,1,n) {
    			int res=0,p=0;
    			rep(j,0,s[i].size()-1) {
    				p=trie[p][s[i][j]-'a'];
    				int x=p;
    				while(~x) {
    					chk(res,tr.Que(1,1,dfn,L[top[x]],L[x]));
    					x=fa[top[x]];
    				}
    			}
    			chk(res,res+val[i]);
    			tr.Upd(1,1,dfn,L[End[i]],res);
    			chk(ans,res);
    			string t;swap(t,s[i]);
    		}
    		printf("Case #%d: %d\n",kase,ans);
    	}
    }
    
    
    
    
    
    
  • 相关阅读:
    单机千万级MQTT连接服务器测试报告
    Esptouch移植xamarin记要
    ubuntu16.04之mongodb自动备份
    Mongodb4.0副本集构建
    golang项目git-subtree完美解决差异包管理
    linux系统优化配置
    IE外挂
    aliyun install Discourse log
    打包前端WebSite到Go程序
    golang channel string 信号乱码
  • 原文地址:https://www.cnblogs.com/chasedeath/p/12931333.html
Copyright © 2020-2023  润新知