• BZOJ2555: SubString


    题解:  建出SAM 用LCT维护Right集合即可

    #include <bits/stdc++.h>
    const int MAXN=3e6+10;
    using namespace std;
    int key[MAXN],dis[MAXN],ch[MAXN][2],chl[MAXN][26],fa[MAXN];
    int pre[MAXN],sum[MAXN],sumx[MAXN];//sum xu sumx all
    bool rt[MAXN];
    int cnt,cur,root,mask;
    char s1[MAXN],s2[MAXN];
    void up(int x){sumx[x]=sumx[ch[x][0]]+sumx[ch[x][1]]+sum[x]+key[x];}
    void Treavel(int x)
    {
        if(x)
        {
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d,sum=%2d,sumx=%2d
    ",x,ch[x][0],ch[x][1],pre[x],key[x],sum[x],sumx[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug(int rp)
    {
        printf("root:%d
    ",rp);
        Treavel(rp);
    }
    void read(int t)
    {
        scanf("%s",s2);
        int i,l = strlen(s2);
        for(i = 0 ; i < l ; i ++ ) t=(t*131+i)%l,swap(s2[i],s2[t]);
    }
    void newnode(int x,int vul){
    	key[x]=sumx[x]=vul;sum[x]=0;rt[x]=1;ch[x][0]=ch[x][1]=0;pre[x]=0;
    }
    void rotate(int x,int kind){
    	int y=pre[x];
    	ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
    	if(rt[y])rt[x]=1,rt[y]=0;
    	else ch[pre[y]][ch[pre[y]][1]==y]=x;
    	pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
    	up(y);
    }
    void splay(int x){
    	while(!rt[x]){
    		if(rt[pre[x]])rotate(x,ch[pre[x]][0]==x);
    		else{
    			int y=pre[x];int kind=ch[pre[y]][0]==y;
    			if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
    			else rotate(y,kind),rotate(x,kind);
    		}
    	}
    	up(x);
    }
    void access(int x){
    	int y=0;
    	while(x){
    		splay(x);
    		if(ch[x][1])pre[ch[x][1]]=x,rt[ch[x][1]]=1,sum[x]+=sumx[ch[x][1]];
    		if(y)rt[y]=0,sum[x]-=sumx[y];
    		ch[x][1]=y;up(x);
    		y=x;x=pre[x];
    	}
    }
    void Link(int u,int v){
    	access(u);splay(u);
    	access(v);splay(v);
    	pre[u]=v;sum[v]+=sumx[u];up(v);
    }
    void destory(int u,int v){
    	access(u);splay(v);
    	ch[v][1]=0;pre[u]=0;rt[u]=1;up(v);
    }
    
    int querty(int x){
    	access(x);splay(x);
    	return sumx[x]-sumx[ch[x][0]];
    }
    void built(int x,int id){
    	int last=cur;cur=++cnt;int p=last;dis[cur]=id;newnode(cur,1);
    	for(;p&&!chl[p][x];p=fa[p])chl[p][x]=cur;
    	if(!p)fa[cur]=root,Link(cur,root);
    	else{
    		int q=chl[p][x];
    		if(dis[q]==dis[p]+1)fa[cur]=q,Link(cur,q);
    		else{
    			int nt=++cnt;dis[nt]=dis[p]+1;newnode(cnt,0);
    			memcpy(chl[nt],chl[q],sizeof(chl[q]));
    			destory(q,fa[q]);
    			fa[nt]=fa[q];Link(nt,fa[q]);fa[q]=fa[cur]=nt;Link(q,nt);Link(cur,nt);
    			for(;chl[p][x]==q;p=fa[p])chl[p][x]=nt;
    		}
    	}
    }
    int slove(){
    	read(mask);int temp=root;int len=strlen(s2);
    	for(int i=0;i<len;i++){
    		int t=s2[i]-'A';
    		if(!chl[temp][t])return 0;
    		temp=chl[temp][t];
    	}
    	int res=querty(temp);mask=mask^res;
    	return res;
    }
    char str[11];
    int main(){
    	int n;scanf("%d",&n);cur=root=cnt=1;newnode(root,0);
    	scanf("%s",s1+1);int len=strlen(s1+1);
    	for(int i=1;i<=len;i++)built(s1[i]-'A',i);
    	mask=0;int num=len;
    	for(int i=1;i<=n;i++){
    		scanf("%s",str);
    		if(str[0]=='Q')printf("%d
    ",slove());
    		else{
    			read(mask);len=strlen(s2);
    			for(int j=0;j<len;j++)num++,built(s2[j]-'A',num);
    		}
    	}
    }
    

    2555: SubString

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 4356  Solved: 1339
    [Submit][Status][Discuss]

    Description

    懒得写背景了,给你一个字符串init,要求你支持两个操作
    (1):在当前字符串的后面插入一个字符串
    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
    你必须在线支持这些操作。

    Input

    第一行一个数Q表示操作个数
    第二行一个字符串表示初始字符串init
    接下来Q行,每行2个字符串Type,Str
    Type是ADD的话表示在后面插入字符串。
    Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
    为了体现在线操作,你需要维护一个变量mask,初始值为0 

        

    读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
    询问的时候,对TrueStr询问后输出一行答案Result
    然后mask=maskxorResult
    插入的时候,将TrueStr插到当前字符串后面即可。
    HINT:ADD和QUERY操作的字符串都需要解压
    长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000
    新加数据一组--2015.05.20

    Output

    Sample Input

    2
    A
    QUERY B
    ADD BBABBBBAAB

    Sample Output

    0
  • 相关阅读:
    asp.net项目发布网上-当前自定义错误设置禁止远程查看应用程序
    TortoiseSVN提交文件的时候卡死
    TortoiseSVN,排除不想提交文件的方法(转)
    VS2010 发布网站时文件丢失
    SQL SERVER2012秘钥
    QTP常用功能
    XAMPP和Bugfree详细教程
    模块
    匿名函数、函数递归与二分法、面向过程
    迭代器、生成式、生成器
  • 原文地址:https://www.cnblogs.com/wang9897/p/9551853.html
Copyright © 2020-2023  润新知