zoukankan      html  css  js  c++  java
  • BZOJ 4327:[JSOI2012]玄武密码

    对于询问串建AC自动机,用母串匹配,标记访问过的节点不再被访问,最后枚举每个串统计答案

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int cnt,tree[10000005][5],a[10000005],len[100005],Fail[10000005],vis[10000005],q[10000005];
    char s[10000005],S[100005][105];
    void update(int x){
    	for (int i=0; i<4; i++)
    		if (!tree[x][i]) tree[x][i]=tree[Fail[x]][i];
    }
    void ac_(){
    	int head=0,tail=0;
    	vis[0]=1;
    	for (int i=0; i<4; i++)
    		if (tree[0][i]){
    			update(tree[0][i]);
    			q[++tail]=tree[0][i];
    			vis[tree[0][i]]=1;
    		}
    	while (head<tail){
    		int x=q[++head];
    		for (int i=0; i<4; i++){
    			int V=tree[x][i];
    			if (vis[V]) continue;
    			Fail[V]=tree[Fail[x]][i];
    			update(V);
    			vis[V]=1;
    			q[++tail]=V;
    		}
    	}
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	scanf("%s",s+1);
    	for (int i=1; i<=n; i++){
    		if (s[i]=='E') a[i]=0;
    		else if (s[i]=='S') a[i]=1;
    		else if (s[i]=='W') a[i]=2;
    		else a[i]=3;
    	}
    	for (int i=1; i<=m; i++){
    		scanf("%s",S[i]+1);
    		len[i]=strlen(S[i]+1);
    		int now=0;
    		for (int j=1; j<=len[i]; j++){
    			int x;
    			if (S[i][j]=='E') x=0;
    			else if (S[i][j]=='S') x=1;
    			else if (S[i][j]=='W') x=2;
    			else x=3;
    			if (!tree[now][x]) tree[now][x]=++cnt;
    			now=tree[now][x];
    		}
    //		sz[now]=1;
    	}
    	ac_();
    //	printf("%d
    ",tree[1][3]);
    	memset(vis,0,sizeof(vis));
    	int now=0;
    	for (int i=1; i<=n; i++){
    		now=tree[now][a[i]];
    //		printf("%d ",now);
    		if (!vis[now]){
    			int Pre=now;
    			vis[Pre]=1;
    			Pre=Fail[Pre];
    			while (!vis[Pre]){
    				vis[Pre]=1;
    				Pre=Fail[Pre];
    			}
    		}
    	}
    //	printf("
    ");
    	for (int i=1; i<=m; i++){
    		int now=0,maxlen=0;
    		for (int j=1; j<=len[i]; j++){
    			int x;
    			if (S[i][j]=='E') x=0;
    			else if (S[i][j]=='S') x=1;
    			else if (S[i][j]=='W') x=2;
    			else x=3;
    			now=tree[now][x];
    			if (!vis[now]) break;
    			maxlen=j;
    		}
    		printf("%d
    ",maxlen);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    CodeForces
    CodeForces
    Simple Robot Gym
    Gym
    Java课程03总结
    Java课程03总结
    判断字符串是否回文
    Java课程02总结
    有关二进制原码、反码、补码
    Java课程01总结
  • 原文地址:https://www.cnblogs.com/silenty/p/9799819.html
Copyright © 2011-2022 走看看