zoukankan      html  css  js  c++  java
  • CF587F. Duff is Mad

    题目描述

    题解

    知道是分块之后就不难了

    把n分块,对于整块建AC自动机暴力跑,散块把全部串建AC自动机之后可以线段树查子树(因为往上查要考虑那些能查那些不能所以不好搞),也可以递归子树时用 出-入 计算

    空间卡一卡可以(nsqrt n),如果再把询问[L,R]前缀和一下之后也许可以做到线性

    时间O(n√n)

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    #define ll long long
    //#define file
    using namespace std;
    
    int bg[100001],ed[100001],A[100011],Tm[100001],n,Q,i,j,k,l,len,S,x,y;
    bool bz[100001];
    ll ans[100001],Ans[100001];
    char st[100001],St[100001];
    struct type{int x,y,z;} q[100001];
    
    namespace tree{
    	int a[100011][2],b[50000001],ls[100011],tr[100011][26],fa[100011],d[100011],Ed[100011],i,j,k,l,len=0,h,t,Len;
    	vector<int> c[100011];
    	ll f[100011];
    	
    	void clear() {memset(tr,0,sizeof(tr[0])*(len+1));memset(fa,0,4*(len+1));memset(f,0,8*(len+1));len=0;}
    	void New(int t,int x) {if (!tr[t][x]) tr[t][x]=++len;}
    	void NEW(int x,int y) {++Len;a[Len][0]=y;a[Len][1]=ls[x];ls[x]=Len;}
    	void dfs(int t)
    	{
    		int i,j,k,l,tot2=c[t].size(),s;
    		
    		fo(i,Ed[t-1]+1,Ed[t]) s=b[i],ans[s]-=f[q[s].z];
    		fo(i,0,tot2-1) ++f[c[t][i]];
    		
    		for (i=ls[t]; i; i=a[i][1]) dfs(a[i][0]);
    		
    		fo(i,Ed[t-1]+1,Ed[t]) s=b[i],ans[s]+=f[q[s].z];
    	}
    	void build(int x,int y,int tp)
    	{
    		clear(),len=1;
    		fo(i,x,y)
    		{
    			l=1;
    			fo(j,bg[i],ed[i])
    			{
    				New(l,st[j]-'a'),l=tr[l][st[j]-'a'];
    				if (tp) c[l].push_back(i);
    			}
    			
    			if (!tp) ++f[l];
    			A[i]=l;
    		}
    		
    		if (tp)
    		{
    			fo(i,1,Q)
    			{
    				for (j=1; j<=n; j+=S)
    				{
    					k=min(j+S-1,n);
    					if (!(q[i].x<=j && k<=q[i].y) || !bz[i])
    					fo(l,max(q[i].x,j),min(q[i].y,k)) ++Ed[A[l]];
    				}
    			}
    			fo(i,1,len) Ed[i]+=Ed[i-1];
    			fd(i,len+1,1) Ed[i]=Ed[i-1];
    			fo(i,1,Q)
    			{
    				for (j=1; j<=n; j+=S)
    				{
    					k=min(j+S-1,n);
    					if (!(q[i].x<=j && k<=q[i].y) || !bz[i])
    					{
    						fo(l,max(q[i].x,j),min(q[i].y,k))
    						b[++Ed[A[l]]]=i;
    					}
    				}
    			}
    		}
    		
    		h=0,t=1;
    		d[1]=1;
    		while (h<t)
    		{
    			++h;
    			fo(i,0,25)
    			if (tr[d[h]][i])
    			{
    				l=tr[d[h]][i];
    				d[++t]=l;
    				
    				j=fa[d[h]];
    				while (j && !tr[j][i]) j=fa[j];
    				fa[l]=(!j)?1:tr[j][i];
    			}
    		}
    		
    		if (!tp)
    		{
    			fo(i,1,t)
    			f[d[i]]+=f[fa[d[i]]];
    		}
    		else
    		{
    			fo(i,2,len) NEW(fa[i],i);
    			dfs(1);
    		}
    	}
    	
    	void js(int t,int id)
    	{
    		ll s=0;
    		if (Tm[t]==x) {ans[id]+=Ans[t];return;}
    		l=1;
    		fo(i,bg[t],ed[t])
    		{
    			while (l && !tr[l][st[i]-'a']) l=fa[l];
    			if (!l) l=1; else l=tr[l][st[i]-'a'];
    			s+=f[l];
    		}
    		Tm[t]=x,Ans[t]=s,ans[id]+=s;
    	}
    };
    
    int main()
    {
    	#ifdef file
    	freopen("CF587F.in","r",stdin);
    	#endif
    	
    	scanf("%d%d",&n,&Q),S=floor(sqrt(n));
    	fo(i,1,n)
    	{
    		scanf("%s",St+1),l=strlen(St+1);
    		bg[i]=len+1;
    		fo(j,1,l) st[++len]=St[j];
    		ed[i]=len;
    	}
    	fo(i,1,Q) scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
    	
    	for (x=1; x<=n; x+=S)
    	{
    		y=min(x+S-1,n);
    		tree::build(x,y,0);
    		
    		fo(i,1,Q)
    		if (q[i].x<=x && y<=q[i].y)
    		tree::js(q[i].z,i),bz[i]=1;
    	}
    	tree::build(1,n,1);
    	
    	fo(i,1,Q) printf("%lld
    ",ans[i]);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    XSS原理及代码分析
    SQL注入原理及代码分析(二)
    SQL注入原理及代码分析(一)
    Kali中密码暴力破解工具hydra的使用
    实战记录之SQL server报错手工注入
    kali下安装beef并联合Metasploit
    kali中安装漏洞靶场Vulhub(超详细)
    kali下一些代理工具的简单描述
    逻辑漏洞之越权漏洞
    ---【hashu】----
  • 原文地址:https://www.cnblogs.com/gmh77/p/13693727.html
Copyright © 2011-2022 走看看