喜闻乐见的LCT+SAM

此题要求动态插入,直接上后缀树。然后询问其实就是求一个节点的子树后缀结束节点的个数。

因为建立后缀树需要插入和删除,就直接上LCT。每次加入一个点,把它到根的路径加一

(现在我才知道access之后那个splay就是这个点到根的路径,LCT学得不好)

思路不需要说太多,就是码量大。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=3001000;
int T,ans;
char s[N];
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int get(int ans){
cin>>s;
int len=strlen(s);
for (int j=0;j<len;j++) {
ans=(ans*131+j)%len;
char c=s[j];
s[j]=s[ans];
s[ans]=c;
}
return len;
}
struct lct{
int fa[N],ch[N][2],w[N],lazy[N],stack[N];
void add(int x,int y){
w[x]+=y;lazy[x]+=y;
}
void pushdown(int x){
if(lazy[x]){
add(ch[x][0],lazy[x]);add(ch[x][1],lazy[x]);
lazy[x]=0;
}
}
bool isroot(int x){
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
bool son(int x){
return ch[fa[x]][1]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y],a=son(x),b=son(y),c=ch[x][!a];
if(!isroot(y))ch[z][b]=x;fa[x]=z;
if(c)fa[c]=y;ch[y][a]=c;
ch[x][!a]=y;fa[y]=x;
}
void splay(int x){
int top=1,a=x;stack[top]=a;
while(a)stack[++top]=a=fa[a];
while(top)pushdown(stack[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(isroot(y))rotate(x);
else{
if(son(x)==son(y))rotate(y);
else rotate(x);
rotate(x);
}
}
}
void access(int x){
for(int j=0;x;j=x,x=fa[x])
splay(x),ch[x][1]=j;
}
void link(int x,int f){
fa[x]=f;access(f);splay(f);add(f,w[x]);
}
void cut(int x){
access(x);splay(x);add(ch[x][0],-w[x]);
fa[ch[x][0]]=0;ch[x][0]=0;
}
}t;
struct SAM{
int tot,u,ln[N],size[N],trans[N][27],fa[N];
void ins(int c){
int x=++tot;ln[x]=ln[u]+1;size[x]=1;
t.w[x]=1;
for(;u&&trans[u][c]==0;u=fa[u])trans[u][c]=x;
if(u==0)fa[x]=1,t.link(x,1);
else{
int v=trans[u][c];
if(ln[v]==ln[u]+1)fa[x]=v,t.link(x,v);
else{
int w=++tot;
ln[w]=ln[u]+1;fa[w]=fa[v];
t.link(w,fa[w]);
memcpy(trans[w],trans[v],sizeof(trans[w]));
fa[x]=fa[v]=w;
t.cut(v);t.link(v,w);t.link(x,w);
for(;u&&trans[u][c]==v;u=fa[u])trans[u][c]=w;
}
}
u=x;
}
void add(){
int len=get(ans);
for(int i=0;i<len;i++)ins(s[i]-'A'+1);
}
int check(){
int len=get(ans);
int now=1;
for(int i=0;i<len;i++){
if(trans[now][s[i]-'A'+1]==0)return 0;
now=trans[now][s[i]-'A'+1];
}
t.splay(now);
return t.w[now];
}
}sam;
int main(){
T=read();
sam.tot=sam.u=1;
cin>>s;
int len=strlen(s);
for(int i=0;i<len;i++)sam.ins(s[i]-'A'+1);
while(T--){
cin>>s;
if(s[0]=='Q'){
int tmp=sam.check();
printf("%d\n",tmp);
ans^=tmp;
}
else sam.add();
}
return 0;
}

BZOJ 2555 SubString(LCT+后缀树)的更多相关文章

  1. bzoj 2555: SubString【后缀自动机+LCT】

    一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的 ...

  2. bzoj 2555: SubString 后缀自动机+LCT

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 688  Solved: 235[Submit][Status][Dis ...

  3. 字符串(LCT,后缀自动机):BZOJ 2555 SubString

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1620  Solved: 471 Description 懒得写背景了 ...

  4. ●BZOJ 2555 SubString

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2555题解: 后缀自动机+LCT 不难发现,对于输入的询问串,在自动机里trans后的到的状态 ...

  5. 2555: SubString[LCT+SAM]

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 2601  Solved: 780 [Submit][Status][ ...

  6. [BZOJ2555]SubString LCT+后缀自动机

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3253  Solved: 975[Submit][Status][Di ...

  7. bzoj 2555 SubString —— 后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 ...

  8. bzoj 2555 SubString——后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 L ...

  9. bzoj 2555 SubString(SAM+LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现 ...

随机推荐

  1. 【AnjularJS系列3 】 — 数据的双向绑定

    第三篇,双向的数据绑定 数据绑定是AnguarJS的特性之一,避免书写大量的初始代码从而节约开发时间 数据绑定指令提供了你的Model投射到view的方法.这些投射可以无缝的,毫不影响的应用到web应 ...

  2. 利用UncaughtExceptionHandler捕获未try...catch到的异常

    public class test { public static void main(String[] args){ Thread thread = new Thread(new MyThread( ...

  3. [USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

    题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N).计算最多有多少 ...

  4. Qt Designer设计 UI 文件并调用

    本文介绍的是Qt Designer设计 UI 文件并调用,在坛子里逛了一圈,关于UI方面的好像不怎多,本篇给大家分享一下. AD: 2013云计算架构师峰会超低价抢票中 Qt Designer设计 U ...

  5. 读取bin文件,并且按结构体赋值打印

    目标:读取一个bin文件,并且将bin文件中的数据,按字节对齐赋值给结构体,并且打印出结构体的内容 目前思路是简单的先将bin文件数据一次性读到一个数组中,再将数组强制转换为结构体 ] FILE *f ...

  6. table的创建

    results为table的行信息 columnNames  是table列名 //创建并初始化table: table =new JTable(results,columNames); //设置ta ...

  7. 一个简单搜索引擎的搭建过程(Solr+Nutch+Hadoop)

    最近,因为未来工作的需要,我尝试安装部署了分布式爬虫系统Nutch,并配置了伪分布式的Hadoop来存储爬取的网页结果,用solr来对爬下来的网页进行搜索.我主要通过参考网上的相关资料进行安装部署的. ...

  8. ActiveMQ_Windows和Linux版本的安装部署

    1, 保证电脑上安装了jdk6以上版本的java,并配置了好环境变量 : 2, 官方下载地址:http://activemq.apache.org/download-archives.html ,这里 ...

  9. volatile 和 mutable 关键字

    经常接触,但是过一段时间可能又忘了.做个记录. volatile是表示变量易变,不要放缓存,每次实际取,尤其是多线程. mutable表示一个const 类或者数据结构里面,某个字段是可以改变的.

  10. JBoss AS 7之文件夹结构(The Return Of The King)

    1.2 JBoss As 7体系结构 以下介绍一下JBoss的体系结构,详细的文件夹结构. 假设熟悉曾经JBoss版本号的人,一定会发现JBoss AS 7与之前的JBoss的文件夹结构有了非常大的不 ...