2555: SubString

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 2548  Solved: 762

Description

懒得写背景了,给你一个字符串init,要求你支持两个操作

(1):在当前字符串的后面插入一个字符串

(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

你必须在线支持这些操作。

Input

第一行一个数Q表示操作个数
    
    第二行一个字符串表示初始字符串init
    
    接下来Q行,每行2个字符串Type,Str 
    
    Type是ADD的话表示在后面插入字符串。
    
    Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
    
    为了体现在线操作,你需要维护一个变量mask,初始值为0
   
    
    读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
    询问的时候,对TrueStr询问后输出一行答案Result
    然后mask = mask xor Result  
    插入的时候,将TrueStr插到当前字符串后面即可。

HINT:ADD和QUERY操作的字符串都需要解压

Output

Sample Input

2

A

QUERY B

ADD BBABBBBAAB

Sample Output

0

HINT

40 % 的数据字符串最终长度 <= 20000,询问次数<= 1000,询问总长度<= 10000

100 % 的数据字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000

新加数据一组--2015.05.20

Source

【分析】

  一开始都没想着用LCT,后来发现我的SAM的right数组一直都是要逆拓扑序求的。

  在线的话,还要在线维护。把pre边看成一棵树,就是要支持link,cut操作的,求子树和的东西。

  其实LCT我只会做路径的,不会做子树了。看了hzwer的代码。【然后好像是,其实也是维护了路径,就是link x和f 的时候就是把f到根的路径都加上val[x]

  【ORZ欧颓果说用splay维护dfs序也可以啊?

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 600010
#define Maxl 3000010 struct node
{
int pre,son[],step;
}t[Maxn*]; struct nnode
{
int son[],fa,val,laz;
nnode() {son[]=son[]=fa=val=laz=;}
}tr[Maxn*]; char s[Maxl];
void init(int mask)
{
scanf("%s",s);
int l=strlen(s);
for(int i=;i<l;i++)
{
mask=(mask*+i)%l;
swap(s[i],s[mask]);
}
} struct lct
{
void add(int x,int y)
{
if(x) tr[x].val+=y,tr[x].laz+=y;
}
bool is_root(int x)
{
return tr[tr[x].fa].son[]!=x&&tr[tr[x].fa].son[]!=x;
}
bool pushdown(int x)
{
int lc=tr[x].son[],rc=tr[x].son[];
if(tr[x].laz)
{
add(lc,tr[x].laz);add(rc,tr[x].laz);
tr[x].laz=;
}
}
void rot(int x)
{
int fa=tr[x].fa,yy=tr[fa].fa;
int w=tr[tr[x].fa].son[]==x; if(!is_root(fa))
{
if(tr[yy].son[]==fa) tr[yy].son[]=x;
else tr[yy].son[]=x;
}tr[x].fa=yy; tr[fa].son[-w]=tr[x].son[w];
tr[tr[x].son[w]].fa=fa; tr[x].son[w]=fa;
tr[fa].fa=x;
//upd(fa);//upd(x);
}
int q[*Maxn];
void pre(int x)
{
int tp=;
while(!is_root(x)) q[++tp]=x,x=tr[x].fa;
q[++tp]=x;
for(int i=tp;i>=;i--) pushdown(q[i]);
}
void splay(int x)
{
pre(x);
while(!is_root(x))
{
int fa=tr[x].fa,yy=tr[fa].fa;
if(!is_root(fa))
{
if((tr[yy].son[]==fa)==(tr[fa].son[]==x)) rot(fa);
else rot(x);
}
rot(x);
}//upd(x);
}
void access(int x)
{
int t=;
while(x)
{
splay(x);
tr[x].son[]=t;
t=x;
x=tr[x].fa;
}
}
/*void split(int x,int y)
{
make_root(x);
access(y);
splay(y);
}*/
void link(int x,int f)
{
tr[x].fa=f;
access(f);
splay(f);
add(f,tr[x].val);
}
void cut(int x)
{
access(x);splay(x);
add(tr[x].son[],-tr[x].val);
tr[tr[x].son[]].fa=;
tr[x].son[]=;
}
}lct; int mask;
struct sam
{
int last,tot;
void extend(int k)
{
int np=++tot,p=last;
t[np].step=t[p].step+;
tr[np].val=;
while(p&&!t[p].son[k])
{
t[p].son[k]=np;
p=t[p].pre;
}
if(!p) t[np].pre=,lct.link(np,);
else
{
int q=t[p].son[k];
if(t[q].step==t[p].step+) t[np].pre=q,lct.link(np,q);
else
{
int nq=++tot;//upd(tot);
t[nq].step=t[p].step+;
memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
t[nq].pre=t[q].pre;
lct.link(nq,t[nq].pre);
t[q].pre=t[np].pre=nq;
lct.cut(q);lct.link(q,nq);lct.link(np,nq);
while(p&&t[p].son[k]==q)
{
t[p].son[k]=nq;
p=t[p].pre;
}
}
}
last=np;
}
void add()
{
init(mask);
int l=strlen(s);
for(int i=;i<l;i++) extend(s[i]-'A'+);
}
int query()
{
init(mask);
int nw=,l=strlen(s);
for(int i=;i<l;i++)
{
int ind=s[i]-'A'+;
if(!t[nw].son[ind]) return ;
nw=t[nw].son[ind];
}
lct.splay(nw);
return tr[nw].val;
}
}sam; char ss[]; int main()
{
int q;
scanf("%d",&q);
sam.tot=sam.last=;
scanf("%s",s);
int l=strlen(s);
for(int i=;i<l;i++) sam.extend(s[i]-'A'+);
while(q--)
{
scanf("%s",ss);
if(ss[]=='A') sam.add();
else
{
int ans=sam.query();
printf("%d\n",ans);
mask^=ans;
}
}
return ;
}

2017-04-19 07:48:14

【BZOJ 2555】 2555: SubString (SAM+LCT)的更多相关文章

  1. bzoj 2555 SubString(SAM+LCT)

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

  2. 【BZOJ 4170】 4170: 极光 (CDQ分治)

    4170: 极光 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 121  Solved: 64 Description "若是万一琪露诺(俗 ...

  3. 【BZOJ 4527】 4527: K-D-Sequence (线段树)

    4527: K-D-Sequence Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 145  Solved: 59 Description 我们称一个 ...

  4. 【BZOJ 2982】 2982: combination (卢卡斯定理)

    2982: combination Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 510  Solved: 316 Description LMZ有n个 ...

  5. 【BZOJ 3262】 3262: 陌上花开 (CDQ分治)

    3262: 陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A ...

  6. 【bzoj 3333】排队计划(线段树)

    n个数,求一次逆序对.接着有m次修改操作,把每次输入的位置p的数之后<=它的数取出来,从小到大排序后再放回空位里,求逆序对.(N,M<=500,000 , Ai<=10^9)思路:1 ...

  7. 2019.03.01 bzoj2555: SubString(sam+lct)

    传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...

  8. 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)

    Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...

  9. 【LOJ#3097】[SNOI2019]通信(费用流)

    [LOJ#3097][SNOI2019]通信(费用流) 题面 LOJ 题解 暴力就直接连\(O(n^2)\)条边. 然后分治/主席树优化连边就行了. 抄zsy代码,zsy代码是真的短 #include ...

随机推荐

  1. RBAC权限系统设计

    序言 RBAC表结构 用户表 角色表 权限表 用户角色(关系)表 角色权限(关系)表 资料 https://blog.csdn.net/ShrMuscles/article/details/80532 ...

  2. Skipping 'Android SDK Tools, revision 24.0.2'; it depends on 'Android SDK Platform-tools, revision 20' which was not installed.

    前几天,同事问我eclipse android sdk怎么不能更新. 更新界面是显示(mirrors.neusoft.edu.cn:80),但是不能更新. 问题描述如下: URL not found: ...

  3. 福建工程学院寒假作业第一周F题

    Subsequence TimeLimit:1000MS  MemoryLimit:65536K 64-bit integer IO format:%lld   问题描述: A sequence of ...

  4. perl6正则 1: ~~ , //, m//, rx//

    ~~ perl6 中, 要匹配一个正则, 使用 ~~ 智能匹配符. > so 'abcde' ~~ /a.c/ True > so 'abcde' ~~ /a.d/ False > ...

  5. videojs做直播、弹幕

    从上一年开始,我们开始接触直播,现在直播成本真的很低,很多CDN供应商都有提供,本文只是大概讲述播放器这个话题. 开始调研 播放格式,我挑了三种.分别是HLS,RTMP,HTTP-FLV. 下面简单说 ...

  6. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  7. c++动态规划dp算法题

    问题1:找硬币,换钱的方法 输入: penny数组代表所有货币的面值,正数不重复 aim小于等于1000,代表要找的钱 输出:换钱的方法总数 解法1:经典dp,空间复杂度O(n*aim) class ...

  8. 记点事! oracle 调用外部命令

    oracle执行系统命令   测试成功环境:windows XP+oracle 10g.window 2008 R2 + 11g   代码如下: www.2cto.com   Sql代码   crea ...

  9. (五)Spring 对事务的支持

    第一节:事务简介 满足一下四个条件: 第一:原子性: 第二:一致性: 第三:隔离性: 第四:持久性: ------------------------------------------------- ...

  10. hdu 5895(矩阵快速幂+欧拉函数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895 f(n)=f(n-2)+2*f(n-1) f(n)*f(n-1)=f(n-2)*f(n-1)+2 ...