●BZOJ 2555 SubString
题链:
http://www.lydsy.com/JudgeOnline/problem.php?id=2555
题解:
后缀自动机+LCT
不难发现,对于输入的询问串,在自动机里trans后的到的状态的Right集合的大小就是答案。
那么后缀自动机本身就是支持在线添加的,问题就是如何维护好parent树,即如何维护好每个状态的Right集合。
那么Link-Cut-Tree就显然可以完成动态维护parent树的任务。
(这里是维护的一颗根固定的树,没有Beroot()等换根函数)
代码:
#include<bits/stdc++.h>
#define MAXN 600005
using namespace std;
int MASK;
struct LCT{
int size;
int ch[MAXN*3][2],fa[MAXN*3],lazy[MAXN*3],val[MAXN*3];
bool Who(int x){return ch[fa[x]][0]!=x;}
bool Isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void Update(int x,int v){val[x]+=v; lazy[x]+=v;}
void Pushdown(int x){
if(!Isroot(x)) Pushdown(fa[x]);
if(!lazy[x]) return;
Update(ch[x][0],lazy[x]);
Update(ch[x][1],lazy[x]);
lazy[x]=0;
}
void Rotate(int x){
static int y,z,l1,l2;
y=fa[x]; z=fa[y];
l1=Who(y); l2=Who(x); fa[x]=z;
if(!Isroot(y)) ch[z][l1]=x;
fa[y]=x; fa[ch[x][l2^1]]=y;
ch[y][l2]=ch[x][l2^1]; ch[x][l2^1]=y;
}
void Splay(int x){
static int y; Pushdown(x);
for(;y=fa[x],!Isroot(x);Rotate(x)) if(!Isroot(y))
Rotate(Who(y)==Who(x)?y:x);
}
void Access(int x){
static int y;
for(y=0;x;y=x,x=fa[x])
Splay(x),ch[x][1]=y;
}
void Link(int x,int y){
Access(x); Splay(x); Update(x,val[y]); fa[y]=x;
}
void Cut(int x){
Access(x);
Splay(x);
Update(ch[x][0],-val[x]);
fa[ch[x][0]]=0; ch[x][0]=0;
}
int Query(int x){
Splay(x); return val[x];
}
}DT;
struct SAM{
int size,last;
int maxs[MAXN*3],trans[MAXN*3][26],parent[MAXN*3];
int Newnode(int a,int b){
++size; maxs[size]=a;
memcpy(trans[size],trans[b],sizeof(trans[b]));
return size;
}
void Extend(int x){
static int p,np,q,nq;
p=last; last=np=Newnode(maxs[p]+1,0);
for(;p&&!trans[p][x];p=parent[p]) trans[p][x]=np;
if(!p) parent[np]=1;
else{
q=trans[p][x];
if(maxs[p]+1!=maxs[q]){
nq=Newnode(maxs[p]+1,q);
parent[nq]=parent[q];
parent[q]=parent[np]=nq;
for(;p&&trans[p][x]==q;p=parent[p]) trans[p][x]=nq;
DT.Cut(q);
DT.Link(parent[nq],nq);
DT.Link(nq,q);
}
else parent[np]=q;
}
DT.val[np]=1;
DT.Link(parent[np],np);
}
void Reset(){
memset(trans[0],0,sizeof(trans[0]));
size=0; last=Newnode(0,0);
}
void Add(char *S){
for(int i=0;S[i];i++) Extend(S[i]-'A');
}
void Query(char *T){
static int p,ans; p=1;
for(int i=0;T[i];i++){
if(!trans[p][T[i]-'A']){
p=0; break;
}
p=trans[p][T[i]-'A'];
}
if(!p) ans=0;
else ans=DT.Query(p);
printf("%d\n",ans);
MASK^=ans;
}
}SUF;
void decode(char *S,int mask){
static int len; len=strlen(S);
for(int i=0;i<len;i++)
mask=(mask*131+i)%len,swap(S[i],S[mask]);
}
int main(){
static char S[MAXN*5],Type[10];
int Q; scanf("%d",&Q);
SUF.Reset();
scanf("%s",S);
SUF.Add(S);
while(Q--){
scanf("%s%s",Type,S);
decode(S,MASK);
if(Type[0]=='A') SUF.Add(S);
else SUF.Query(S);
}
return 0;
}
●BZOJ 2555 SubString的更多相关文章
- bzoj 2555: SubString 后缀自动机+LCT
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 688 Solved: 235[Submit][Status][Dis ...
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1620 Solved: 471 Description 懒得写背景了 ...
- bzoj 2555 SubString(SAM+LCT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现 ...
- bzoj 2555 SubString——后缀自动机+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 L ...
- bzoj 2555 SubString —— 后缀自动机+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 ...
- bzoj 2555: SubString
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支 ...
- 【刷题】BZOJ 2555 SubString
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支 ...
- bzoj 2555: SubString【后缀自动机+LCT】
一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的 ...
- BZOJ 2555: SubString 后缀自动机_LCT
很水的一道题,就是有些细节没注意到. 比如说将调试信息误以为是最终结果而多调了20分钟QAQ ..... 我们注意到,每新加一个节点,改变的是该节点沿着 Parent 走一直走到根节点. 对应的,在 ...
随机推荐
- 201621123057 《Java程序设计》第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现什 ...
- JAVA线程概念
一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在 ...
- 关于collectionView和tableView的两种cell的出列方法的区别
相信好多人一定会对collectionView和tableView的两种cell出列方法有所疑问,下面以UICollection为例子进行举例说明 假设我们已经创建了一个collectionView, ...
- 亚马逊AWS学习——EC2的自定义VPC配置
1 网络配置 EC2即亚马逊AWS云服务中的虚拟主机.创建EC2实例时如果使用的默认VPC并分配了公有IP是可以上网的.但我们经常需要自定义的网络环境,这时就需要自己定义VPC和子网了. 1.1 配置 ...
- 【基础知识】Flex-弹性布局原来如此简单!!
简言 布局的传统解决方案是基于盒状模型,依赖 display + position + float 方式来实现,灵活性较差.2009年,W3C提出了一种新的方案-Flex,Flex是Flexible ...
- 点击一次按钮,发生多次ajax请求
项目中遇到了两种情况: 1.点击一次发生两次请求. 原因:submit类型的按钮,默认有提交行为,发生两次提交的原因是在执行完ajax请求后,并没有阻止submit的行为,所以解决方法有两种: a.不 ...
- angular2 学习笔记 ( 第3方插件 jQuery and ckeditor )
refer : https://forums.meteor.com/t/importing-ckeditor-using-npm/28919/2 (ckeditor) https://github ...
- 新概念英语(1-43)Hurry up!
新概念英语(1-43)Hurry up! How do you know Sam doesn't make the tea very often? A:Can you make the tea, Sa ...
- Object.defineProperties()和Object.defineProperty()方法
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...
- 日推20单词 Day02
1.distinguish v. 区别,辨别 2.tension n. 紧张,不安 3.sympathy n. 同情,慰问 4.admiration n. 羡慕 5.jealousy n. 嫉妒 6. ...