zoukankan      html  css  js  c++  java
  • BZOJ 2434: [Noi2011]阿狸的打字机 AC自动机+fail树+线段树

    Description

     阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。

    经阿狸研究发现,这个打字机是这样工作的:

    l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。

    l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。

    l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失。

    例如,阿狸输入aPaPBbP,纸上被打印的字符如下:

    a

    aa

    ab

    我们把纸上打印出来的字符串从1开始顺序编号,一直到n。打字机有一个非常有趣的功能,在打字机中暗藏一个带数字的小键盘,在小键盘上输入两个数(x,y)(其中1≤x,y≤n),打字机会显示第x个打印的字符串在第y个打印的字符串中出现了多少次。

    阿狸发现了这个功能以后很兴奋,他想写个程序完成同样的功能,你能帮助他么?

    Input

     输入的第一行包含一个字符串,按阿狸的输入顺序给出所有阿狸输入的字符。

    第二行包含一个整数m,表示询问个数。

    接下来m行描述所有由小键盘输入的询问。其中第i行包含两个整数x, y,表示第i个询问为(x, y)。

    Output

     输出m行,其中第i行包含一个整数,表示第i个询问的答案。

    这道题和前几天在 CF 上做的一道 G题几乎是相同的. 

    不知道为什么那场比赛切掉 G 题的人会那么少~ 

    回到本题,不难发现打字机给出的其实就是 trie 的形式. 

    把 $trie$ 建出来后和 $fail$ 树一起跑,然后用线段树维护 dfs 序就好了. 

    #include <queue> 
    #include <cstdio> 
    #include <cstring>
    #include <vector> 
    #include <algorithm>  
    #define N 300003 
    #define setIO(s) freopen(s".in","r",stdin)   
    using namespace std;  
    struct Seg  {  
    	#define lson (now<<1) 
    	#define rson (now<<1|1)  
    	struct Node { 
    		int sum; 
    	}t[N<<2]; 
    	void update(int l,int r,int now,int p,int v)  {  
    		t[now].sum+=v; 
    		if(l==r) return; 
    		int mid=(l+r)>>1; 
    		if(p<=mid) update(l,mid,lson,p,v); 
    		else update(mid+1,r,rson,p,v); 
    	} 
    	int query(int l,int r,int now,int L,int R) {
    		if(l>=L&&r<=R) return t[now].sum; 
    		int mid=(l+r)>>1,re=0; 
    		if(L<=mid) re+=query(l,mid,lson,L,R); 
    		if(R>mid)  re+=query(mid+1,r,rson,L,R); 
    		return re; 
    	}
    	#undef lson 
    	#undef rson 
    }seg; 
    struct Node {   
    	int ch[27],f,end;  
    }t[N];
    struct Ask { 
    	int i,y; 
    	Ask(int i=0,int y=0):i(i),y(y){}   
    }; 
    struct Graph { 
    	int edges; 
    	int hd[N],to[N],nex[N],fa[N],val[N]; 
    	void addedge(int u,int v,int c) {
    		nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;   
    	}  
    }trie,tree; 
    queue<int>q; 
    vector<Ask>G[N];   
    int n,m,tot,tim,id[N],que[N],answer[N],dfn[N],size[N]; 
    char op[N]; 
    void buildAC() {
    	int i,j; 
    	for(i=0;i<27;++i) if(t[0].ch[i]) q.push(t[0].ch[i]); 
    	while(!q.empty()) {
    		int u=q.front();q.pop(); 
    		for(i=0;i<27;++i) {
    			int p=t[u].ch[i]; 
    			if(!p) {
    				t[u].ch[i]=t[t[u].f].ch[i]; 
    				continue;  
    			} 
    			t[p].f=t[t[u].f].ch[i]; 
    			q.push(p);   
    		}
    	}
    } 
    void dfs(int u) { 
    	dfn[u]=++tim, size[u]=1; 
    	for(int i=tree.hd[u];i;i=tree.nex[i]) 
    		dfs(tree.to[i]), size[u]+=size[tree.to[i]];     
    }
    void buildtree() { 
    	for(int i=1;i<=tot;++i) tree.addedge(t[i].f, i,0);      
    	dfs(0); 
    }
    void solve(int now,int x) {
    	seg.update(1,tim,1,dfn[now],1);    
    	for(int i=0;i<G[x].size();++i) 
    		answer[G[x][i].i]=seg.query(1,tim,1,dfn[G[x][i].y],dfn[G[x][i].y]+size[G[x][i].y]-1);    
    	for(int i=trie.hd[x];i;i=trie.nex[i]) {
    		int v=trie.to[i],c=trie.val[i];  
    		solve(t[now].ch[c], v);  
    	}
    	seg.update(1,tim,1,dfn[now],-1); 
    } 
    int main() {
    	int i,j,lst=0,cc=0; 
    	// setIO("input");              
    	scanf("%s",op+1),n=strlen(op+1);
    	for(i=1;i<=n;++i) {
    		if(op[i]>='a'&&op[i]<='z') {     
    			int c=op[i]-'a'; 
    			if(!t[lst].ch[c]) {
    				t[lst].ch[c]=++tot; 
    				trie.addedge(lst,tot,c); 
    				trie.fa[tot]=lst;   
    			}
    			id[i]=lst=t[lst].ch[c];              
    		}
    		else { 
    			if(op[i]=='P') que[++cc]=i,id[i]=lst;    
    			if(op[i]=='B') id[i]=lst=trie.fa[lst];        
    		}          
    	} 
    	buildAC();
    	buildtree();   
    	scanf("%d",&m); 
    	for(i=1;i<=m;++i) {
    		int x,y; 
    		scanf("%d%d",&x,&y); 
    		x=id[que[x]],y=id[que[y]];     
    		G[y].push_back(Ask(i,x));           
    	} 
    	solve(0,0);   
    	for(i=1;i<=m;++i) printf("%d
    ",answer[i]);         
    	return 0; 
    }
    

      

  • 相关阅读:
    丁子鸣-第一次个人编程作业
    丁子鸣---第一次个人作业
    How U.S. Stock Prices Correlate to the Value of the U.S. Dollar 美股价格和美元价值的关联
    在win10上WSL怎么显示GUI
    android 6.0.1 compiling
    Python Virtual Environments: A Primer
    ubuntu stardict 字典
    opencv Functionality Overview
    msm-v2 7af6000.i2c: error Missing 'i2c' DT entry
    Bash Shortcuts For Maximum Productivity
  • 原文地址:https://www.cnblogs.com/guangheli/p/11422738.html
Copyright © 2011-2022 走看看