bzoj2555: SubString

题意

考虑第一问所求即为该串对应的节点的子树内终止节点的个数,而插入一个字符相当于在新增节点到根节点的链+1,于是用LCT维护。

code:

#include<bits/stdc++.h>
using namespace std;
#define re register
const int maxn=1200010;
int Q,mask,ans;
char s[3000010];
string chars;
void gets(int mask)
{
    scanf("%s",s);
    chars=s;
    for(re int j=0;j<(int)chars.length();j++) 
	{
        mask=(mask*131+j)%chars.length();
        char t=chars[j];
        chars[j]=chars[mask];
        chars[mask]=t;
    }
}
struct LCT
{
	int top;
	int fa[maxn],val[maxn],tag[maxn],sta[maxn];
	int ch[maxn][2];
	inline int get(int x){return ch[fa[x]][1]==x;}
	inline bool checkroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
	inline void down(int x)
	{
		if(!tag[x])return;
		re int k=tag[x];tag[x]=0;
		if(ch[x][0])val[ch[x][0]]+=k,tag[ch[x][0]]+=k;
		if(ch[x][1])val[ch[x][1]]+=k,tag[ch[x][1]]+=k;
	}
	inline void rotate(int x)
	{
		re int y=fa[x],z=fa[y],k=get(x),w=ch[x][k^1];
		if(!checkroot(y))ch[z][get(y)]=x;ch[x][k^1]=y;ch[y][k]=w;
		if(w)fa[w]=y;fa[x]=z;fa[y]=x;
	}
	inline void splay(int x)
	{
		re int now=x;
		sta[top=1]=now;
		while(!checkroot(now))sta[++top]=fa[now],now=fa[now];
		while(top)down(sta[top--]);
		while(!checkroot(x))
		{
			re int y=fa[x];
			if(!checkroot(y))rotate(get(x)==get(y)?y:x);
			rotate(x);
		}
	}
	inline void access(int x){for(re int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y;}
	inline void link(int x,int y)
	{
		fa[x]=y;access(y);splay(y);
		val[y]+=val[x];tag[y]+=val[x];
	}
	inline void cut(int x)
	{
		access(x);splay(x);
		val[ch[x][0]]-=val[x],tag[ch[x][0]]-=val[x];
		ch[x][0]=fa[ch[x][0]]=0;
	}
}tree;
struct SAM
{
	int tot,last;
	int fa[maxn],len[maxn];
	int ch[maxn][30];
	SAM(){last=tot=1;}
	inline void add(int c)
	{
		re int now=++tot;len[now]=len[last]+1;tree.val[now]=1;
		re int p=last;last=now;
		while(p&&!ch[p][c])ch[p][c]=now,p=fa[p];
		if(!p){fa[now]=1;tree.link(now,1);return;}
		re int q=ch[p][c];
		if(len[q]==len[p]+1)fa[now]=q,tree.link(now,q);
		else 
		{
			re int nowq=++tot;
			memcpy(ch[nowq],ch[q],sizeof(ch[q]));
			fa[nowq]=fa[q];tree.link(nowq,fa[q]);
			tree.cut(q);fa[q]=fa[now]=nowq;tree.link(q,nowq),tree.link(now,nowq);
			while(p&&ch[p][c]==q)ch[p][c]=nowq,p=fa[p];
		}
	}
	inline void build()
	{
		scanf("%s",s+1);re int len=strlen(s+1);
		for(re int i=1;i<=len;i++)add(s[i]-'A');
	}
	inline void extend()
	{
		gets(mask);
		re int len=chars.size();
		for(re int i=0;i<len;i++)add(chars[i]-'A');
	}
	inline int query()
	{
		gets(mask);
		re int now=1,len=chars.size();
		for(re int i=0;i<len;i++)
		{
			if(!ch[now][chars[i]-'A'])return 0;
			now=ch[now][chars[i]-'A'];
		}
		tree.splay(now);
		return tree.val[now];
	}
}sam;
int main()
{
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
	scanf("%d",&Q);
	sam.build();
	while(Q--)
	{
		char op[10];scanf("%s",op+1);
		if(op[1]=='A')sam.extend();
		else printf("%d\n",ans=sam.query()),mask^=ans;
	}
	return 0;
}
posted @ 2019-12-17 16:44  nofind  阅读(84)  评论(0编辑  收藏  举报