zoukankan      html  css  js  c++  java
  • 【CF587F】Duff is Mad AC自动机+分块

    【CF587F】Duff is Mad

    题意:给出n个串$s_1,s_2..s_n$,有q组询问,每次给出l,r,k,问你编号在[l,r]中的所有串在$s_k$中出现了多少次。

    $sum|s_i|,qle 10^5$

    题解:先将询问离线,改成前缀相减。然后建出AC自动机,考虑分块。

    对于长度$>sqrt n$的询问串,这种串最多$sqrt n$个,我们每次可以扫一遍整个fail树,处理出每个节点到根的路径上有多少个询问串中的点。然后将所有串一个一个加入到fail树里,假如加入的串的结束节点到根路径上有a个询问串种的点,则答案+=a。

    对于长度$<sqrt n$的串,我们按编号一个一个处理。我们加入一个串时,要将其结束节点的fail树子树中所有节点的点权都+1。放到DFS序上就是区间+操作。我们再次分块便可做到$O(1)-O(sqrt n)$的复杂度。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    using namespace std;
    const int maxn=100010;
    typedef long long ll;
    int n,m,B,tot,cnt;
    ll sum;
    struct node
    {
    	int ch[26],fail;
    }p[maxn];
    struct query
    {
    	int x,k,org;
    	query() {}
    	query(int a,int b,int c) {x=a,k=b,org=c;}
    };
    int lp[maxn],rp[maxn],q[maxn],pos[maxn],head[maxn],to[maxn],nxt[maxn],p1[maxn],p2[maxn];
    ll ans[maxn],s[maxn],sb[1000];
    char str[maxn];
    vector<query> v1[maxn],v2[maxn];
    vector<query>::iterator it;
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    inline void build()
    {
    	int i,u,h=1,t=0;
    	q[++t]=1;
    	while(h<=t)
    	{
    		u=q[h++];
    		for(i=0;i<26;i++)
    		{
    			if(p[u].ch[i])
    			{
    				q[++t]=p[u].ch[i];
    				if(u==1)	p[p[u].ch[i]].fail=1;
    				else	p[p[u].ch[i]].fail=p[p[u].fail].ch[i];
    			}
    			else
    			{
    				if(u==1)	p[u].ch[i]=1;
    				else	p[u].ch[i]=p[p[u].fail].ch[i];
    			}
    		}
    	}
    }
    bool cmp(const query &a,const query &b)
    {
    	return a.x<b.x;
    }
    inline void add(int a,int b)
    {
    	to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
    }
    void dfs(int x)
    {
    	p1[x]=++p2[0];
    	for(int i=head[x];i!=-1;i=nxt[i])	dfs(to[i]);
    	p2[x]=p2[0];
    }
    inline void upd(int a,int b)
    {
    	int i,c=a/B,d=b/B;
    	if(c==d)	for(i=a;i<=b;i++)	s[i]++;
    	else
    	{
    		for(i=a;i<c*B+B;i++)	s[i]++;
    		for(i=d*B;i<=b;i++)	s[i]++;
    		for(i=c+1;i<d;i++)	sb[i]++;
    	}
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,u,a,b,c;
    	tot=1;
    	for(i=1;i<=n;i++)
    	{
    		lp[i]=rp[i-1],scanf("%s",str+lp[i]),rp[i]=lp[i]+strlen(str+lp[i]);
    		for(u=1,j=lp[i];j<rp[i];j++)
    		{
    			a=str[j]-'a';
    			if(!p[u].ch[a])	p[u].ch[a]=++tot;
    			u=p[u].ch[a];
    		}
    		pos[i]=u;
    	}
    	build(),B=int(sqrt(double(tot+1)));
    	for(i=1;i<=m;i++)
    	{
    		a=rd(),b=rd(),c=rd();
    		if(rp[c]-lp[c]>B)
    		{
    			if(a!=1)	v2[c].push_back(query(a-1,-1,i));
    			v2[c].push_back(query(b,1,i));
    		}
    		else
    		{
    			if(a!=1)	v1[a-1].push_back(query(c,-1,i));
    			v1[b].push_back(query(c,1,i));
    		}
    	}
    	memset(head,-1,sizeof(head));
    	for(i=2;i<=tot;i++)	add(p[i].fail,i);
    	dfs(1);
    	for(i=1;i<=n;i++)
    	{
    		upd(p1[pos[i]],p2[pos[i]]);
    		for(it=v1[i].begin();it!=v1[i].end();it++)
    		{
    			a=(*it).x,b=(*it).k,c=(*it).org;
    			for(u=1,j=lp[a];j<rp[a];j++)
    			{
    				u=p[u].ch[str[j]-'a'];
    				ans[c]+=(s[p1[u]]+sb[p1[u]/B])*b;
    			}
    		}
    	}
    	for(i=1;i<=n;i++)	if(rp[i]-lp[i]>B&&v2[i].size())
    	{
    		memset(s,0,sizeof(s));
    		for(u=1,j=lp[i];j<rp[i];j++)	u=p[u].ch[str[j]-'a'],s[u]++;
    		for(j=tot;j>=2;j--)	s[p[q[j]].fail]+=s[q[j]];
    		sort(v2[i].begin(),v2[i].end(),cmp);
    		for(sum=0,j=1,it=v2[i].begin();it!=v2[i].end();it++)
    		{
    			a=(*it).x,b=(*it).k,c=(*it).org;
    			while(j<=a)	sum+=s[pos[j++]];
    			ans[c]+=b*sum;
    		}
    	}
    	for(i=1;i<=m;i++)	printf("%lld
    ",ans[i]);
    	return 0;
    }//
  • 相关阅读:
    spring事物配置,声明式事务管理和基于@Transactional注解的使用
    spring集成ehcache本地缓存
    Java并发编程:volatile关键字解析
    Callable接口、Runable接口、Future接口
    Sorting It All Out
    Borg Maze
    Agri-Net
    Highways
    Truck History
    Arbitrage
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8682046.html
Copyright © 2011-2022 走看看