• HDU 6096 String(AC自动机+树状数组)


    题意

    给定 (n) 个单词,(q) 个询问,每个询问包含两个串 (s_1,s_2),询问有多少个单词以 (s_1) 为前缀, (s_2) 为后缀,前后缀不能重叠。

    (1 leq n,q leq 10^5)

    思路

    字符串题有一个小技巧,拼接字符串,中间加上连接符。如这道题,可以将查询变成 (s_2+ ext{{}+s_1) 的形式,相应的,把单词 (T) 变为 (T+ ext{{}+T) 的形式。那么就是普通的匹配问题了。

    对于询问建立( ext{AC})自动机。同样发现一个匹配指针遍历到节点 (u) 时,(u)(fail) 树上的父节点也得配。但这道题,直接树上差分并未考虑前后缀不能重叠的约束条件。不难发现,我们只要先将更新和查询按照长度从大到小进行归并就可以解决这个问题,直接把树上差分改成在线的树状数组维护 ( ext{dfs}) 序即可。

    代码

    #include<bits/stdc++.h>
    #define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
    #define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
    typedef long long LL;
    using namespace std;
    const int N=1e5+5;
    const int M=5e5+5;
    template<const int maxn,const int maxm>struct Linked_list
    {
    	int head[maxn],to[maxm],nxt[maxm],tot;
    	Linked_list(){clear();}
    	void clear(){memset(head,-1,sizeof(head));}
    	void add(int u,int v){to[++tot]=v,nxt[tot]=head[u],head[u]=tot;}
    	#define EOR(i,G,u) for(int i=G.head[u];~i;i=G.nxt[i])
    };
    struct FenwickTree
    {
    	#define lowbit(x) ((x)&-(x))
    	int c[M*2],n;
    	void build(int _n){n=_n;memset(c,0,sizeof(c));}
    	void update(int k,int val){for(;k<=n;k+=lowbit(k))c[k]+=val;}
    	int query(int k){int res=0;for(;k>0;k^=lowbit(k))res+=c[k];return res;}
    	int query(int l,int r){return query(r)-query(l-1);}
    	#undef lowbit
    };
    Linked_list<M*2,M*2>G;
    FenwickTree FT;
    int ch[M*2][27],f[M*2];
    int rt,tot;
    int L[M*2],R[M*2],ord;
    string P[N],T[N],s1,s2;
    int Plen[N],Tlen[N];
    int p[N],t[N];
    int Output[N];
    int n,q;
    
    bool cmp_T(int x,int y){return Tlen[x]>Tlen[y];}
    bool cmp_P(int x,int y){return Plen[x]>Plen[y];}
    void build(){rt=tot=0;}
    void create(int &k)
    {
    	if(!k)
    	{
    		k=++tot;
    		FOR(i,0,26)ch[k][i]=0;
    	}
    }
    void insert(int &k,string &str)
    {
    	create(k);
    	int now=k;
    	FOR(i,0,str.length()-1)
    	{
    		create(ch[now][str[i]-'a']);
    		now=ch[now][str[i]-'a'];
    	}
    }
    void get_fail()
    {
    	queue<int>Q;
    	while(!Q.empty())Q.pop();
    	f[rt]=rt;
    	FOR(i,0,26)
    	{
    		if(ch[rt][i])f[ch[rt][i]]=rt,Q.push(ch[rt][i]);
    		else ch[rt][i]=rt;
    	}
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		FOR(i,0,26)
    		{
    			if(ch[u][i])f[ch[u][i]]=ch[f[u]][i],Q.push(ch[u][i]);
    			else ch[u][i]=ch[f[u]][i];
    		}
    	}
    }
    void dfs_fail(int u)
    {
    	L[u]=++ord;
    	EOR(i,G,u)dfs_fail(G.to[i]);
    	R[u]=ord;
    }
    void update(string &str)
    {
    	int now=rt;
    	FOR(i,0,(int)str.length()-1)
    	{
    		now=ch[now][str[i]-'a'];
    		FT.update(L[now],1);
    	}
    }
    int query(string &str)
    {
    	int now=rt;
    	FOR(i,0,(int)str.length()-1)
    		now=ch[now][str[i]-'a'];
    	return FT.query(L[now],R[now]);
    }
    
    int main()
    {
    	int Case;
    	scanf("%d",&Case);
    	while(Case--)
    	{
    		build();
    		scanf("%d%d",&n,&q);
    		FOR(i,1,n)
    		{
    			cin>>s1;
    			Tlen[i]=s1.length();
    			T[i]=s1+'{'+s1;
    		}
    		FOR(i,1,q)
    		{
    			cin>>s1>>s2;
    			Plen[i]=s1.length()+s2.length();
    			P[i]=s2+'{'+s1;
    		}
    		
    		FOR(i,1,q)insert(rt,P[i]);
    		G.clear();FT.build(tot);
    		get_fail();
    		FOR(i,1,tot)if(f[i]!=i)G.add(f[i],i);
    		ord=0;dfs_fail(rt);
    		
    		FOR(i,1,n)t[i]=i;
    		FOR(i,1,q)p[i]=i;
    		sort(t+1,t+1+n,cmp_T);
    		sort(p+1,p+1+q,cmp_P);
    		
    		int upd=1;
    		FOR(qry,1,q)
    		{
    			while(upd<=n&&Tlen[t[upd]]>=Plen[p[qry]])
    				update(T[t[upd]]),upd++;
    			Output[p[qry]]=query(P[p[qry]]);
    		}
    		
    		FOR(i,1,q)printf("%d
    ",Output[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java 8 CompletableFuture思考
    Math.ceil 笔记
    Python virtual env
    Reactive Stream: 如何将两个数据流接到一起,然后进行操作
    基于Apollo实现.NET Core微服务统一配置(测试环境-单机)
    在ASP.NET Core 2.x中获取客户端IP地址
    Entity Framework Core(3)-配置DbContext
    .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能
    Entity Framework Core 入门(2)
    Entity Framework Core介绍(1)
  • 原文地址:https://www.cnblogs.com/Paulliant/p/10229336.html
Copyright © 2020-2023  润新知