bzoj2555
开始时间:19:40
完成时间:21:00
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555
题目大意:(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 1200005
#define maxl 3000005
using namespace std;
int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn];
char st[maxl];
char ss[];
struct data{
int fa[maxn],son[maxn][];
int isroot(int x) {return (son[fa[x]][]!=x && son[fa[x]][]!=x);}
int which(int x){return son[fa[x]][]==x;}
void change(int x,int k){ ri[x]+=k; lazy[x]+=k;}
void pushdown(int x)
{
if (!lazy[x]) return;
if (son[x][]) change(son[x][],lazy[x]);
if (son[x][]) change(son[x][],lazy[x]);
lazy[x]=;
}
void relax(int x){if (!isroot(x)) relax(fa[x]); pushdown(x);}
void turn(int x){
int y=fa[x],wx=which(x),wy=which(y);
if (!isroot(y)) son[fa[y]][wy]=x; fa[x]=fa[y];
son[y][wx]=son[x][-wx]; fa[son[x][-wx]]=y;
son[x][-wx]=y; fa[y]=x;
}
void splay(int x)
{
relax(x);
while (!isroot(x))
{
if (isroot(fa[x])) turn(x);
else if (which(x)==which(fa[x])) turn(fa[x]),turn(x);
else turn(x),turn(x);
}
}
void access(int x)
{
for (int p=; x; x=fa[x]){ splay(x); son[x][]=p; p=x;}
}
void link(int x,int y){
fa[x]=y; access(y); splay(y); change(y,ri[x]);
}
void cut(int x)
{
access(x); splay(x); change(son[x][],-ri[x]); fa[son[x][]]=; son[x][]=;
}
}lct;
struct date{
int fa[maxn],son[maxn][],val[maxn];
void prepare(){root=tot=last=;}
int newnode(int x){val[++tot]=x; return tot;}
void extend(int x)
{
int p=last,np=newnode(val[p]+);ri[np]=;last=np;
for (; p&&!son[p][x]; p=fa[p]) son[p][x]=np;
if (!p) fa[np]=root,lct.link(np,root);
else
{
int q=son[p][x];
if (val[q]==val[p]+){fa[np]=q; lct.link(np,q);}
else
{
int nq=newnode(val[p]+);ri[nq]=;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; lct.cut(q),lct.link(nq,fa[nq]);
fa[q]=fa[np]=nq; lct.link(q,nq),lct.link(np,nq);
for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq;
}
}
}
void build()
{for (int i=; i<=m; i++) extend(st[i]-'A');}
void query(){
int x,y;
bool can=;
x=root;
for (int i=;i<=m;i++){
y=st[i]-'A';
if (!son[x][y]){
can=;
break;
}else{
x=son[x][y];
}
}
if (can==||x==root) puts("");
else{
lct.splay(x);
printf("%d\n",ri[x]),mark^=ri[x];
}
}
}SAM;
void unzip(){
int temp=mark;
for (int i=;i<=m;i++){
temp=(temp*+i-)%m+;
char t=st[i]; st[i]=st[temp],st[temp]=t,temp--;
}
}
int main()
{
scanf("%d\n",&q);mark=;
scanf("%s",st+); m=strlen(st+);
SAM.prepare();
SAM.build();
for (int i=; i<=q; i++)
{
scanf("%s",ss);scanf("%s",st+); m=strlen(st+);unzip();
if (ss[]=='A') SAM.build();
else SAM.query();
}
}
bzoj2555的更多相关文章
- 【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)
[BZOJ2555]SubString(后缀自动机,Link-Cut Tree) 题面 BZOJ 题解 这题看起来不难 每次要求的就是\(right/endpos\)集合的大小 所以搞一个\(LCT\ ...
- 【bzoj2555】 SubString
http://www.lydsy.com/JudgeOnline/problem.php?id=2555 (题目链接) 题意 给出一个初始串,维护两个操作.在原串后面加入一个字符串:询问某个字符串在原 ...
- 【BZOJ2555】SubString 后缀自动机+LCT
[BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2 ...
- BZOJ2555 SubString【SAM + Link Cut Tree】
BZOJ2555. SubString 要求在线询问一个串在原串中出现的次数,并且可以在原串末尾添加字符串 如果没有修改的话,考虑建出\(parent\)树之后统计每个\(endpos\)节点的\(r ...
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1936 Solved: 551[Submit][Status][Di ...
- bzoj2555: SubString
SAM+LCT维护parent tree版本 虽然说子树维护那套理论需要ETT 不过parent tree的根是固定的,所以用lct加一些奇怪的乱搞就行了 //随手拖个SAM的板子和LCT的板子,然后 ...
- BZOJ2555——SubString
0.题目很短,就不概括了 给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. ...
- bzoj2555(后缀自动机+LCT)
题目描述 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 题解 做法很自然,建出后缀自动机,维护每个节点的right ...
- 【BZOJ2555】SubString
算是学会sam了吧…… 原题: 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了 ...
随机推荐
- 使用ADO对象添加、修改、删除数据
使用ADO对象对数据库中的数据进行添加.修改和删除等操作.首先创建一个ADO类,通过ADO类连接数据库,并打开记录集.例如,使用ADO对象添加.修改.删除数据,程序设计步骤如下:(1)创建一个基于对话 ...
- Django: 之Web框架完美解析
Web框架解析 Web通过Socket来监听客户端,,一旦发现客户发送的信息立刻接受.接受之后在服务端查找客户的请求,找到请求返回给用户,断开.这是一个连接,不断的接收,不断的返回. #!/usr/b ...
- 剑指offer替换空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- Socket在手机上的应用
usb读取:pid vid --可以唯一的确定设备获取手机驱动socket固定端口通信 wifipc机在局域网内,udp的数据包(整个网段) 蓝牙配对 bluetoothsocket 如果放大:可以分 ...
- android4.0蓝牙使能的详细解析(转)
源:http://www.cnblogs.com/xiaochao1234/p/3818193.html 本文详细分析了android4.0 中蓝牙使能的过程,相比较android2.3,4.0中的蓝 ...
- VC6.0 调试.dll文件
对于自己制作的.DLL文件,一直没有比较好的调试方法,其实是知道的太少. 下面就说说VC6.0下面 怎么调试DLL文件: 首先得有一个调用DLL文件的可执行程序,然后调用这个可执行程序. 在工程上 右 ...
- HDFS读写程序小测试
WriteHdfs: package aa; import java.io.*; import org.apache.hadoop.conf.Configuration; import org.apa ...
- Android性能优化典范---转
Android性能优化典范 原文链接: http://hukai.me/android-performance-patterns/ JAN 17TH, 2015 | COMMENTS 2015新年伊 ...
- Htpasswd 给网站后台目录加密
http://www.l0phtcrack.com/download.html打开apache配置文件 httpd.conf 配置如下: <Directory "/var/www/ ...
- JAVA实现的截屏程序
http://hadeslee.iteye.com/blog/125386 http://www.jb51.net/article/75114.htm JAVA截屏程序(第三版) JavaEXTSwi ...