算是学会sam了吧……

原题:

懒得写背景了,给你一个字符串init,要求你支持两个操作
    
    (1):在当前字符串的后面插入一个字符串
    
    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
    
    你必须在线支持这些操作。
   字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000

因为sam添点本来就是动态的所以动态往后连接串就不用管了

问题是维护right集的大小,如果新添了一个点np那么从np一直到sam的根right集的大小都会+1对吧

暴力修改即可?以前是可以的,现在新添一组数据卡掉了……

那咋办,动态树上进行路径修改,lct口贝

值得注意的是修改的路径是当前点到原树根的,lct上修改的时候需要把原树根钦定为lct的根然后再access再splay再修改

注意询问串可能比插入串和起始串长,如果共用一个字符数组的话要开成3e6……

注意题中给出的强制在线函数中mask是个局部变量……也就是说转码的时候mask不会变,询问的时候才会变……

代码:

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int qwq=;
int m; char s[],t[]; int n;
int nxt[][],fth[],mx[],sz[],lst=,npt=;
int c[][],fa[],v[],dt[],rvs[];
int stck[],tp=;
inline bool isrt(int x){ return (c[fa[x]][]!=x)&(c[fa[x]][]!=x);}
inline void pshd(int x){
v[c[x][]]+=dt[x],dt[c[x][]]+=dt[x];
v[c[x][]]+=dt[x],dt[c[x][]]+=dt[x];
dt[x]=;
if(!rvs[x]) return ;
rvs[c[x][]]^=,rvs[c[x][]]^=,rvs[x]=;
swap(c[x][],c[x][]);
}
inline void rtt(int x){
int y=fa[x],z=fa[fa[x]],l,r;
r=(c[y][]==x); l=r^;
if(!isrt(y)) c[z][c[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
}
inline void sply(int x){
stck[tp=]=x;
for(int i=x;!isrt(i);i=fa[i]) stck[++tp]=fa[i];
while(tp) pshd(stck[tp--]);
while(!isrt(x)){
if(!isrt(fa[x])) rtt((c[fa[x]][]==x)^(c[fa[fa[x]]][]==fa[x])?x:fa[x]);
rtt(x);
}
}
inline void accs(int x){ for(int i=;x;sply(x),c[x][]=i,x=fa[i=x]);}
inline void qdrt(int x){ accs(x),sply(x),rvs[x]^=;}
inline void lk(int x,int y){ qdrt(x),fa[x]=y,sply(x);}
inline void ct(int x,int y){ qdrt(x),accs(y),sply(y),fa[x]=c[y][]=;}
inline void bf(int x,int y){ qdrt(),accs(x),sply(x),v[x]+=y,dt[x]+=y;}
inline int sch(int x){ sply(x); return v[x];}
void rds(){
scanf("%s",s); n=strlen(s); int tmp=qwq;
for(int i=;i<n;++i){
tmp=(tmp*+i)%n;
swap(s[i],s[tmp]);
}
}
/*void ist(int x){
int p=lst,np=lst=++npt;
mx[np]=mx[p]+1; sz[np]=0;
while((!nxt[p][x])&((!p)^1)) nxt[p][x]=np,p=fth[p];
if(!p) fth[np]=1;
else{
int q=nxt[p][x];
if(mx[q]==mx[p]+1) fth[np]=q;
else{
int nq=++npt; mx[nq]=mx[p]+1; sz[nq]=sz[q];
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fth[nq]=fth[q],fth[q]=fth[np]=nq;
while(nxt[p][x]==q) nxt[p][x]=nq,p=fth[p];
}
}
while(np) ++sz[np],np=fth[np];
}*/
void ist(int x){
int p=lst,np=lst=++npt;
mx[np]=mx[p]+; v[np]=;
while((!nxt[p][x])&((!p)^)) nxt[p][x]=np,p=fth[p];
if(!p) fth[np]=,lk(np,);
else{
int q=nxt[p][x];
if(mx[q]==mx[p]+) fth[np]=q,lk(np,q);
else{
int nq=++npt; mx[nq]=mx[p]+; v[nq]=sch(q);
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
ct(q,fth[q]),lk(nq,fth[q]),lk(q,nq),lk(np,nq);
fth[nq]=fth[q],fth[q]=fth[np]=nq;
while(nxt[p][x]==q) nxt[p][x]=nq,p=fth[p];
}
}
bf(np,);
//cout<<sch(5)<<" "<<fth[3]<<endl;
}
int qr(){
int tmp=;
for(int i=;i<n;++i) tmp=nxt[tmp][s[i]-'A'];
return tmp?sch(tmp):;
}
int main(){freopen("ddd.in","r",stdin);
cin>>m; scanf("%s",s); n=strlen(s);
for(int i=;i<n;++i) ist(s[i]-'A');
while(m--){
scanf("%s",t); rds();
if(t[]=='A') for(int i=;i<n;++i) ist(s[i]-'A');
else{ int tmp=qr(); qwq^=tmp; printf("%d\n",tmp);}
}
return ;
}

【BZOJ2555】SubString的更多相关文章

  1. 【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)

    [BZOJ2555]SubString(后缀自动机,Link-Cut Tree) 题面 BZOJ 题解 这题看起来不难 每次要求的就是\(right/endpos\)集合的大小 所以搞一个\(LCT\ ...

  2. 【BZOJ2555】SubString 后缀自动机+LCT

    [BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作         (1):在当前字符串的后面插入一个字符串         (2 ...

  3. 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree

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

  4. 【bzoj2555】 SubString

    http://www.lydsy.com/JudgeOnline/problem.php?id=2555 (题目链接) 题意 给出一个初始串,维护两个操作.在原串后面加入一个字符串:询问某个字符串在原 ...

  5. 【BZOJ2555】SubString(后缀自动机,LCT)

    题意:给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 长度 <= ...

  6. 【leetcode】Substring with Concatenation of All Words

    Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that ar ...

  7. 【leetcode】Substring with Concatenation of All Words (hard) ★

    You are given a string, S, and a list of words, L, that are all of the same length. Find all startin ...

  8. 【LeetCode】哈希表 hash_table(共88题)

    [1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...

  9. 【LeetCode】字符串 string(共112题)

    [3]Longest Substring Without Repeating Characters (2019年1月22日,复习) [5]Longest Palindromic Substring ( ...

随机推荐

  1. 5、zabbix使用进阶(01)

    详细描述user parameters.定义主机发现规则实现自动发现.如何定义和实现自动注册方式 zabbix常用术语 1.主机(host):要监控的网络设备,可有IP或DNS名称指定: 2.主机组( ...

  2. 【HAOI 2012】高速公路

    Problem Description \(Y901\) 高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站. \(Y901\) ...

  3. WIN8外包公司—长年承接WIN8(surface)应用外包—北京动点飞扬软件

    WIN8外包公司—长年承接WIN8(surface)应用外包 一.我们长年专门承接WIN8外包.Surface外包. WPF 外包.HTML5外包.WindowsPhone 外包.Silverligh ...

  4. 《Visual C#从入门到精通》第四章使用复合赋值和循环语句——读书笔记

    第1章 使用复合赋值和循环语句 4.1 使用复合赋值操作符 任何算术操作符都可以像这样与赋值操作符合并,从而获得复合赋值操作符. 不要这样写 要这样写 Variable=Variable*number ...

  5. [数据结构]P1.3 栈 Stack

    * 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 栈是一种先进后出的结构(FILO),常见的操作有:push 入栈.pop删除栈顶元素并返回.peek 查看栈顶元素 与其他线性结构一 ...

  6. 利用Fiddler编写Jmeter接口测试

    利用Fiddler抓包APP应用接口,在Jmeter编写接口测试脚本 1.用Fiddler对Android用用进行抓包 Fiddler介绍: Fiddler是一款非常流行并且实用的http抓包工具,它 ...

  7. National Property CodeForces - 875C (拓扑排序)

    大意: n个字符串, 每次操作选出一种字符全修改为大写, 求判断能否使n个字符串字典序非降. 建源点s, 汇点t, s与所有必须转大写的连边, 必须不转大写的与t连边. #include <io ...

  8. StringEscapeUtils对字符串进行各种转义与反转义

    项目过程中导出的word无法打开,发现是由于里面有&字符造成,需要进行HTML字符的转义: StringEscapeUtils.escapeHtml4(“需要转义的字符”); 已解决. 参考: ...

  9. zabbix3.4.7使用过程中常见错误

    ================================================================================================ 1.Z ...

  10. LeetCode 总结,二叉树各种类型问题小结

    三大遍历 前序遍历 中序遍历 后序遍历 关于三大基础遍历,必须要条件反射式的记住:三种遍历的迭代方式使用的都是栈,后序遍历必须使用了 两个栈,其余乱七八糟的解决方式统统就不要再记了. 广度遍历: 分析 ...