zoukankan      html  css  js  c++  java
  • BZOJ2555 Substring

    传送门

    样例毒瘤 强制在线毒瘤(

    做法比较显然啦 我们需要维护一个SAM 并资磁查询子树大小

    由于强制在线 所以就需要LCT咯

    查询子树大小我们可以变成链加+单点查询

    然后匹配过程就和ACA的跳跳跳一样啦

     decode这个地方真的坑 mask要设局部变量

    附代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ls(x) t[x].son[0]
    #define rs(x) t[x].son[1]
    #define fa(x) t[x].fa
    #define not_root(x) (ls(fa(x))==x||rs(fa(x))==x)
    #define inf 20021225
    #define ll long long
    #define mxn 600000
    using namespace std;
    
    struct node{int fa,son[26],val,tag;};
    struct tree
    {
    	node t[mxn*4];
    	void pushdown(int x)
    	{
    		if(!x)	return;
    		if(t[x].tag)
    		{
    			int tag=t[x].tag;
    			if(ls(x))	t[ls(x)].val+=tag,t[ls(x)].tag+=tag;
    			if(rs(x))	t[rs(x)].val+=tag,t[rs(x)].tag+=tag;
    			t[x].tag=0;
    		}
    	}
    	void pushup(int x)
    	{
    		if(!x)	return;
    		t[x].val=t[ls(x)].val+t[rs(x)].val;
    	}
    	void rotate(int x)
    	{
    		if(!not_root(x)||!x)	return;
    		int f=fa(x),gf=fa(f);
    		int k=rs(f)==x,p=k^1;
    		if(not_root(f))	t[gf].son[rs(gf)==f]=x;
    		t[x].fa=gf;t[f].fa=x;
    		if(t[x].son[p])	t[t[x].son[p]].fa=f;
    		t[f].son[k]=t[x].son[p];
    		t[x].son[p]=f;
    	}
    	void push(int x)
    	{
    		if(not_root(x))	push(fa(x));
    		pushdown(x);
    	}
    	void splay(int x)
    	{
    		push(x);
    		while(not_root(x))
    		{
    			int f=t[x].fa,gf=t[f].fa;
    			if(not_root(f))
    				(rs(f)==x)^(rs(gf)==f)?rotate(x):rotate(f);
    			rotate(x);
    		}
    	}
    	void access(int x)
    	{
    		int y=0;
    		do
    		{
    			splay(x);
    			t[x].son[1]=y;
    			y=x;x=t[x].fa;
    		}while(x);
    	}
    	void link(int x,int y) // link x to y
    	{
    		t[x].fa=y; access(y); splay(y); t[y].tag+=t[x].val; t[y].val+=t[x].val;
    	}
    	void cut(int x)// cut x
    	{
    		access(x); splay(x);
    		t[ls(x)].tag-=t[x].val; t[ls(x)].val-=t[x].val;
    		t[ls(x)].fa=0; t[x].son[0]=0;
    	}
    }lct;
    struct point{int len,fa,ch[2];};
    struct sam
    {
    	point pt[mxn*4];
    	int rt,poi,lt;
    	void insert(int c)
    	{
    		int p=lt,np=lt=++poi; pt[np].len=pt[p].len+1;
    		lct.t[np].val=1;
    		for(; p&& !pt[p].ch[c];p=pt[p].fa)	pt[p].ch[c]=np;
    		if(!p){lct.link(np,rt);pt[np].fa=rt;return;}
    		int q=pt[p].ch[c];
    		if(pt[q].len==pt[p].len+1){lct.link(np,q);pt[np].fa=q;return;}
    		int nq=++poi; pt[nq].len=pt[p].len+1;
    		memcpy(pt[nq].ch,pt[q].ch,sizeof(pt[q].ch));
    		lct.cut(q); pt[nq].fa=pt[q].fa; lct.link(nq,pt[q].fa);
    		pt[q].fa=pt[np].fa=nq; lct.link(q,nq); lct.link(np,nq);
    		for(;p&&pt[p].ch[c]==q;p=pt[p].fa)	pt[p].ch[c]=nq;
    	}
    	void init()
    	{
    		rt=lt=++poi;
    	}
    	void build(char s[])
    	{int n=strlen(s);
    		for(int i=0;i<n;i++)	insert(s[i]-'A');
    	}
    	int getans(char s[])
    	{
    		int pos=rt;int n=strlen(s);
    		for(int i=0;i<n;i++)
    		{
    			if(pt[pos].ch[s[i]-'A'])	pos=pt[pos].ch[s[i]-'A'];
    			else	return 0;
    		}
    		//printf("QAQ");
    		lct.access(pos); lct.splay(pos); return lct.t[pos].val;
    	}
    }sam;
    char s[mxn];
    void decodewithMask(int mask)
    {
    	int n=strlen(s);
    	for(int i=0;i<n;i++)
    	{
    		mask=(mask*131+i)%n;
    		swap(s[i],s[mask]);
    	}
    }
    char cz[10];
    int main()
    {
    	int q,mask=0,ans=0;
    	//freopen("2.in","r",stdin);
    	scanf("%d",&q);
    	scanf("%s",s);sam.init();sam.build(s);
    	for(int i=0;i<q;i++)
    	{
    		scanf("%s",cz);
    		scanf("%s",s);
    		decodewithMask(mask);
    		if(cz[0]=='A')	sam.build(s);
    		else	ans=sam.getans(s),printf("%d
    ",ans),mask^=ans;
    	}
    	return 0;
    }
    /**
    2
    AB
    ADD BBABB
    QUERY BB
    */
  • 相关阅读:
    Makefile中的ifeq 多条件使用
    Android引入动态库so的方法
    在Win10上使用Visual Studio2015的Android模拟器
    linux下insmod模块出现“Invalid parameters"
    在干净的ubuntu 14.10上编译Qemu2.2.0的过程
    Windows下struct和union字节对齐设置以及大小的确定(一 简介和结构体大小的确定)
    C++类中一个构造函数调用另一个构造函数
    用汇编语言角度来理解C语言的一些问题
    TCP协议的安全性分析
    MySQL入门,第四部分,学会创建、删除表
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321913.html
Copyright © 2011-2022 走看看