zoukankan      html  css  js  c++  java
  • loj6031.「雅礼集训 2017 Day1」字符串

    题意

    注意到询问串的长度(k)是给定的,同时(sumlimits len_w=kqleqslant10^5),我们发现(k,q)之间一个大了另一个必定会小,因此我们对(k)分类讨论:
    首先肯定要对(s)建一个后缀自动机,对每个点维护(endpos)集合的大小。

    (kgeqslantsqrt{n})

    这时(qleqslantsqrt{n}),我们直接在(SAM)暴力匹配(w),找出所有(w)的前缀对应的节点,之后枚举询问,倍增跳到(w[l_i...r_i])这个节点,将答案加上该节点的(endpos)集合大小即可。

    (k<sqrt{n})

    这时(m)组询问中的种类很少,我们可以枚举(w)的所有子串,算出它在([l,r])这段询问区间中出现的次数,乘上它的答案加到答案中。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define re register
    #define pii pair<int,int>
    #define mkp make_pair
    #define fir first
    #define sec second
    const int maxn=2e5+10;
    const int maxt=410;
    int n,m,Q,K,tot,cnt_edge,t;
    int head[maxn],size[maxn],pos[maxn],posl[maxn];
    int f[maxn][18];
    char s[maxn];
    inline int read()
    {
    	char c=getchar();re int res=0,f=1;
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    	return res*f;
    }
    struct edge{int to,nxt;}e[maxn];
    inline void add_edge(int u,int v)
    {
    	e[++cnt_edge].nxt=head[u];
    	head[u]=cnt_edge;
    	e[cnt_edge].to=v;
    }
    struct Query{int l,r;}qr[maxn];
    struct SAM
    {
    	int last,tot;
    	int fa[maxn],len[maxn];
    	int ch[maxn][26];
    	SAM(){last=tot=1;}
    	inline void add(int c)
    	{
    		re int now=++tot;len[now]=len[last]+1;
    		re int p=last;last=now;
    		while(p&&!ch[p][c])ch[p][c]=now,p=fa[p];
    		if(!p){fa[now]=1;return;}
    		re int q=ch[p][c];
    		if(len[q]==len[p]+1)fa[now]=q;
    		else
    		{
    			re int nowq=++tot;len[nowq]=len[p]+1;
    			memcpy(ch[nowq],ch[q],sizeof(ch[q]));
    			fa[nowq]=fa[q];fa[q]=fa[now]=nowq;
    			while(p&&ch[p][c]==q)ch[p][c]=nowq,p=fa[p];
    		}
    	}
    }sam;
    void dfs(int x)
    {
    	for(re int i=1;i<=17;i++)f[x][i]=f[f[x][i-1]][i-1];
    	for(re int i=head[x];i;i=e[i].nxt)
    	{
    		re int y=e[i].to;
    		f[y][0]=x;dfs(y);
    		size[x]+=size[y];
    	}
    }
    inline void solve1()
    {
    	vector<int>a[maxt][maxt];
    	for(int i=1;i<=m;i++)a[qr[i].l][qr[i].r].push_back(i);
    	while(Q--)
    	{
    		scanf("%s",s+1);
    		int l=read()+1,r=read()+1;
    		ll res=0;
    		for(int i=1;i<=K;i++)
    			for(int j=i,now=1;j<=K;j++)
    			{
    				now=sam.ch[now][s[j]-'a'];
    				if(!now)break;
    				int ql=lower_bound(a[i][j].begin(),a[i][j].end(),l)-a[i][j].begin();
    				int qr=upper_bound(a[i][j].begin(),a[i][j].end(),r)-a[i][j].begin();
    				res+=1ll*(qr-ql)*size[now];
    			}
    		printf("%lld
    ",res);
    	}
    }
    inline int find(int l,int r)
    {
    	re int now=pos[r];
    	for(re int i=17;~i;i--)if(sam.len[f[now][i]]>=min(r-l+1,posl[r]))now=f[now][i];
    	return now;
    }
    inline int solve(int l,int r)
    {
    	if(!pos[r]||posl[r]<(r-l+1))return 0;;
    	re int now=find(l,r);
    	if(sam.len[now]>=r-l+1)return size[now];
    	else return 0;
    }
    inline void solve2()
    {
    	while(Q--)
    	{
    		scanf("%s",s+1);
    		re int l=read()+1,r=read()+1;
    		re int now=1,nowl=0,res=0;
    		for(re int i=1;i<=K;i++)
    		{
    			re int c=s[i]-'a';
    			while(!sam.ch[now][c]&&now)now=sam.fa[now],nowl=sam.len[now];
    			if(!now){now=1;pos[i]=1;nowl=0;posl[i]=0;continue;}
    			now=sam.ch[now][c];pos[i]=now;
    			nowl++;posl[i]=nowl;
    		}	
    		for(re int i=l;i<=r;i++)res+=solve(qr[i].l,qr[i].r);
    		printf("%d
    ",res);
    	}
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	n=read(),m=read(),Q=read(),K=read();t=330;
    	scanf("%s",s+1);
    	for(re int i=1;i<=n;i++)sam.add(s[i]-'a'),size[sam.last]=1;
    	for(re int i=2;i<=sam.tot;i++)add_edge(sam.fa[i],i);
    	dfs(1);
    	for(re int i=1;i<=m;i++)qr[i].l=read()+1,qr[i].r=read()+1;
    	if(K<=t)solve1();
    	else solve2();
    	return 0;
    } 
    
  • 相关阅读:
    PAT (Advanced Level) 1060. Are They Equal (25)
    PAT (Advanced Level) 1059. Prime Factors (25)
    PAT (Advanced Level) 1058. A+B in Hogwarts (20)
    PAT (Advanced Level) 1057. Stack (30)
    PAT (Advanced Level) 1056. Mice and Rice (25)
    PAT (Advanced Level) 1055. The World's Richest (25)
    PAT (Advanced Level) 1054. The Dominant Color (20)
    PAT (Advanced Level) 1053. Path of Equal Weight (30)
    PAT (Advanced Level) 1052. Linked List Sorting (25)
    PAT (Advanced Level) 1051. Pop Sequence (25)
  • 原文地址:https://www.cnblogs.com/nofind/p/12149765.html
Copyright © 2011-2022 走看看