zoukankan      html  css  js  c++  java
  • 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
    ",ans=sam.query()),mask^=ans;
    	}
    	return 0;
    }
    
  • 相关阅读:
    centos上安装禅道
    BootStrap-Table主子表
    开源项目学习
    javascript字面量
    linux下vi的一些简单的操作
    vuejs 开发中踩到的坑
    leetcode 220. Contains Duplicate III 求一个数组中有没有要求的元素 ---------- java
    leetcode 219. Contains Duplicate II 求一个数组中有没有重复元素 ---------- java
    leetcode 1
    leetcode 217. Contains Duplicate 求一个数组中有没有重复元素 ---------- java
  • 原文地址:https://www.cnblogs.com/nofind/p/12055370.html
Copyright © 2011-2022 走看看