zoukankan      html  css  js  c++  java
  • HDU6069 String

    题目

    Bob has a dictionary with N words in it.
    Now there is a list of words in which the middle part of the word has continuous letters disappeared. The middle part does not include the first and last character.
    We only know the prefix and suffix of each word, and the number of characters missing is uncertain, it could be 0. But the prefix and suffix of each word can not overlap.
    For each word in the list, Bob wants to determine which word is in the dictionary by prefix and suffix.
    There are probably many answers. You just have to figure out how many words may be the answer.

    大意是给你一个前缀一个后缀,问能够同时满足这个前缀和后缀的串有多少个。

    思路

    这里有一个非常巧妙的处理方法,一般很难想到:把待匹配的串T转化为T+'{'+T的形式,把前缀s1和后缀s2转化为s2+'{'+s1的形式。这样就把原问题转化为了一个普通的字符串匹配问题,只要dfs一遍fail树,把子树信息统计上来就行了。

    然而,注意题目中还有一个限制条件:前缀后缀不能重叠,也就意味着我们还要维护一维信息。

    所以只要把这一维用树状数组,然后dfs作差就好了。

    代码

    #include<bits/stdc++.h>
    #define M 1000005
    #define clr(x,y) memset(x,y,sizeof(x))
    using namespace std;
    int T,n,q,ans[M];
    char S[M],wk[M<<1];
    char S1[M],S2[M];
    int h[M],tot;
    struct que{int id,l;};
    vector<que>Q[M];
    int pre[M];
    struct edge{
    	int nxt,to;
    }G[M<<1];
    void Add(int a,int b){
    	G[++tot]=(edge){h[a],b};
    	h[a]=tot;	
    }
    struct BIT{
    	int C[M];
    	void clear(){
    		clr(C,0);	
    	}
    	void add(int x,int d){
    		x++;
    		while(x<M){
    			C[x]+=d;
    			x+=(x&-x);	
    		}
    	}
    	int sum(int x){
    		int res=0;
    		x++;
    		while(x){
    			res+=C[x];
    			x-=(x&-x);
    		}
    		return res;
    	}
    }TT;
    struct AC_automaton{
    	int tt;
    	int pa[M][27];
    	int f[M];
    	vector<int>val[M];
    	void clear(){
    		clr(pa[0],0);
    		clr(f,0);
    		for(int i=0;i<=tt;i++)val[i].clear();
    		tt=0;
    	}
    	int Insert(char *S,int d){
    		int u=0,l=strlen(S);
    		for(int i=0;i<l;i++){
    			int c=S[i]-'a';
    			if(!pa[u][c]){
    				pa[u][c]=++tt;
    				clr(pa[tt],0);
    				Q[tt].clear();
    			}
    			u=pa[u][c];
    			if(d!=-1)val[u].push_back(d);
    		}
    		return u;
    	}
    	void get_fail(){
    		queue<int>Q;
    		for(int i=0;i<=26;i++){
    			if(pa[0][i]!=0){
    				f[pa[0][i]]=0;
    				Q.push(pa[0][i]);	
    			}
    		}
    		while(!Q.empty()){
    			int u=Q.front();Q.pop();
    			for(int i=0;i<=26;i++){
    				if(pa[u][i]!=0){
    					f[pa[u][i]]=pa[f[u]][i];
    					Q.push(pa[u][i]);
    				}
    				else pa[u][i]=pa[f[u]][i];
    			}
    		}
    		for(int i=1;i<=tt;i++)if(f[i]!=i)Add(f[i],i);
    	}
    }Tr;
    void jie(char *s1,char *s2,char *s3){
    	int l1=strlen(s1);
    	int l2=strlen(s2);
    	int l3=0;
    	for(int i=0;i<l1;i++)s3[l3++]=s1[i];
    	s3[l3++]='{';
    	for(int i=0;i<l2;i++)s3[l3++]=s2[i];
    }
    int find(char *s){
    	int l=strlen(s),u=0;
    	for(int i=0;i<l;i++){
    		if(!Tr.pa[u][s[i]-'a'])return -1;
    		u=Tr.pa[u][s[i]-'a'];
    	}
    	return u;
    }
    void dfs(int x){
    	for(int i=0;i<Q[x].size();i++)
    		pre[Q[x][i].id]=TT.sum(M-1)-TT.sum(Q[x][i].l-1);
    	for(int i=0;i<Tr.val[x].size();i++)
    		TT.add(Tr.val[x][i],1);
    	for(int i=h[x];i;i=G[i].nxt)dfs(G[i].to);
    	for(int i=0;i<Q[x].size();i++)
    		ans[Q[x][i].id]=TT.sum(M-1)-TT.sum(Q[x][i].l-1)-pre[Q[x][i].id];
    }
    int main(){
    	cin>>T;
    	while(T--){
    		Tr.clear();clr(h,0);tot=0;
    		TT.clear();clr(ans,0);
    		scanf("%d%d",&n,&q);
    		for(int i=1;i<=n;i++){
    			scanf("%s",S);
    			int l=strlen(S);
    			jie(S,S,wk);
    			wk[l+l+1]=0;
    			Tr.Insert(wk,strlen(S));
    		}
    		for(int i=1;i<=q;i++){
    			scanf("%s%s",S1,S2);
    			jie(S2,S1,wk);
    			wk[strlen(S1)+strlen(S2)+1]=0;
    			int k=Tr.Insert(wk,-1);
    			if(k==-1)ans[i]=0;
    			else Q[k].push_back((que){i,strlen(wk)-1});
    		}
    		Tr.get_fail();
    		dfs(0);
    		for(int i=1;i<=q;i++)
    			printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    大数据应用之双色球算奖平台总体设计数据规模估算篇
    正能量之项目经理的自我修养
    从郭美美霸气侧漏看项目管理之项目经理防身术
    虚拟化技术纲要之虚拟化技术发展简史
    从国足1:5输泰国看项目管理之项目失败责任该有谁负
    分享一个有趣的代码,调用电脑中的api语音
    EXTJS组件的XTYPE属性列表
    FileSaver.js 浏览器导出Excel文件
    c#简单自定义异常处理日志辅助类
    批处理bat命令--获取当前盘符和当前目录和上级目录
  • 原文地址:https://www.cnblogs.com/zryabc/p/10467531.html
Copyright © 2011-2022 走看看