zoukankan      html  css  js  c++  java
  • BZOJ2555 SubString(后缀自动机+LCT)

      询问串放在SAM上不跳fail跑到的节点的|right|即为答案。用LCT维护parent树即可。可以直接维护子树信息,也可以转化为路径加。注意强制在线所使用的mask是作为参数传进去的。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 1300010
    #define lson tree[k].ch[0]
    #define rson tree[k].ch[1]
    #define lself tree[tree[k].fa].ch[0]
    #define rself tree[tree[k].fa].ch[1]
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int Q,n,m,cnt=1,last=1,son[N][26],fail[N],len[N],mask;
    char s[N],t[N];
    struct data{int ch[2],fa,rev,s,sv,x; 
    }tree[N];
    void up(int k){tree[k].s=tree[k].sv+tree[lson].s+tree[rson].s+tree[k].x;}
    void rev(int k){if (k) swap(lson,rson),tree[k].rev^=1;}
    void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=0;}
    int whichson(int k){return rself==k;}
    bool isroot(int k){return lself!=k&&rself!=k;}
    void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);}
    void move(int k)
    {
    	int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
    	if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
    	tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
    	tree[k].ch[!p]=fa,tree[fa].fa=k;
    	up(fa),up(k);
    }
    void splay(int k) 
    {
    	push(k);
    	while (!isroot(k))
    	{
    		int fa=tree[k].fa;
    		if (!isroot(fa))
    			if (whichson(fa)^whichson(k)) move(k);
    			else move(fa);
    		move(k);
    	}
    }
    void access(int k)
    {
    	for (int t=0;k;t=k,k=tree[k].fa)
    	{
    		splay(k);
    		tree[k].sv+=tree[rson].s-tree[t].s; 
    		rson=t;
    		up(k);
    	}
    }
    void makeroot(int k){access(k),splay(k),rev(k);}
    void link(int x,int y){makeroot(x);access(y),splay(y);tree[x].fa=y;tree[y].sv+=tree[x].s;up(y);}
    void cut(int x,int y){makeroot(x),access(y),splay(y);tree[y].ch[0]=tree[x].fa=0;up(y);}
    int query(int k){if (!k) return 0;makeroot(1);access(k),splay(k);return tree[k].s-tree[lson].s;}
    void decode(int mask)
    {
    	for (int j=0;j<m;j++)
    	{
    		mask=(mask*131+j)%m;
    		char u=t[j];t[j]=t[mask];t[mask]=u;
    	}
    }
    void relink(int x,int y)
    {
    	if (fail[x]) cut(x,fail[x]);
    	fail[x]=y;link(x,y);
    }
    void ins(int c)
    { 
    	int x=++cnt,p=last;len[x]=len[p]+1;last=x;tree[x].x=tree[x].s=1;
    	while (!son[p][c]&&p) son[p][c]=x,p=fail[p];
    	if (!p) relink(x,1);
    	else
    	{
    		int q=son[p][c];
    		if (len[p]+1==len[q]) relink(x,q);
    		else
    		{
    			int y=++cnt;
    			len[y]=len[p]+1;
    			memcpy(son[y],son[q],sizeof(son[q]));
    			relink(y,fail[q]);
    			relink(q,y);
    			relink(x,y);
    			while (son[p][c]==q) son[p][c]=y,p=fail[p];
    		}
    	}
    }
    int run(char *s)
    {
    	int k=1;
    	for (int i=0;i<m;i++) k=son[k][s[i]-'A'];
    	return k;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	const char LL[]="%I64d
    ";
    #else
    	const char LL[]="%lld
    ";
    #endif
    	Q=read();scanf("%s",s);n=strlen(s);
    	for (int i=0;i<n;i++) ins(s[i]-'A');
    	while (Q--)
    	{
    		scanf("%s",t);
    		if (t[0]=='A')
    		{
    			scanf("%s",t);m=strlen(t);
    			decode(mask);
    			for (int i=0;i<m;i++) ins(t[i]-'A');
    		}
    		else
    		{
    			scanf("%s",t);m=strlen(t);
    			decode(mask);
    			int ans=query(run(t));
    			printf("%d
    ",ans);
    			mask^=ans;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    C# 设计原则-单一职责原则
    C# Linq的简单运用
    .Net Core中的管道机制
    .Net Core和.Net Framework的区别
    C# 9.0 新特性简析
    .Net core的依赖注入
    .Net IOC容器unity的使用
    网站被黑客攻击百度出现警示
    七牛云免费对象存储(解决图片加载缓慢问题)
    今天第一篇博客 说点随意的内容
  • 原文地址:https://www.cnblogs.com/Gloid/p/10820556.html
Copyright © 2011-2022 走看看