用SAM支持往末尾在线添加字符的功能。

设$f[i][j]$表示右端点为i的每个左端点的答案,那么当$i$变为$i+1$时,在SAM的parent链形成的树中会新增一个叶子$p$。

对于每个节点,维护它最后一次出现的位置的右端点$v$,那么加入$p$的时候,需要把它到根路径上所有节点的$v$都改为$i+1$,而它们之前的$v$值就是它们倒数第二次出现的位置,可以用$v$来更新答案。

用LCT维护parent树,那么赋值为一种新的颜色可以用access操作实现,经过的每条实链的$v$值都相同。

而在这条实链中,找出最短和最长的子串,那么长度介于它们之间的子串均以$v$结尾作为倒数第二次出现。

对于$f[i+1][]$来说,等价于一段前缀区间取最大值,中间一段贡献一个等差数列,线段树维护即可。

为了在线回答询问,将线段树可持久化即可。

时间复杂度$O(n\log^2n)$。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010,M=N<<1,E=20000000;
int n,m,i,op,x,y,ans;char a[N];
int tot=1,last=1,pre[M],son[M][26],ml[M];
int T[N],cnt,l[E],r[E],v[E],RT[N],TOT,L[E],R[E],V[E];
inline void umin(int&a,int b){ml[a]>ml[b]?(a=b):0;}
inline void umax(int&a,int b){a<b?(a=b):0;}
int change(int x,int a,int b,int c,int d,int p){
int y=++cnt;
l[y]=l[x],r[y]=r[x],v[y]=v[x];
if(c<=a&&b<=d){
umax(v[y],p);
return y;
}
int mid=(a+b)>>1;
if(c<=mid)l[y]=change(l[x],a,mid,c,d,p);
if(d>mid)r[y]=change(r[x],mid+1,b,c,d,p);
return y;
}
int cal(int x,int a,int b,int c){
if(a==b)return v[x];
int mid=(a+b)>>1;
return max(v[x],c<=mid?cal(l[x],a,mid,c):cal(r[x],mid+1,b,c));
}
int ins(int x,int a,int b,int c,int d){
int y=++TOT;
V[y]=max(V[x],d);
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)L[y]=ins(L[x],a,mid,c,d),R[y]=R[x];else L[y]=L[x],R[y]=ins(R[x],mid+1,b,c,d);
return y;
}
int ask(int x,int a,int b,int c,int d){
if(c<=a&&b<=d)return V[x];
int mid=(a+b)>>1,t=0;
if(c<=mid)t=ask(L[x],a,mid,c,d);
if(d>mid)umax(t,ask(R[x],mid+1,b,c,d));
return t;
}
inline void modify(int v,int l,int r){
if(!v||l>r)return;
RT[n]=ins(RT[n],1,100000,v-r+1,r);
T[n]=change(T[n],1,100000,v-r+1,v-l+1,v);
}
namespace LCT{
int f[M],son[M][2],vis[M],tag[M],mi[M],ma[M],a[M];
inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
inline void tag1(int x,int p){
if(!x)return;
umax(vis[x],p),umax(tag[x],p);
}
inline void pb(int x){if(tag[x])tag1(son[x][0],tag[x]),tag1(son[x][1],tag[x]),tag[x]=0;}
inline void up(int x){
mi[x]=x,ma[x]=ml[x];
if(son[x][0])umin(mi[x],mi[son[x][0]]),umax(ma[x],ma[son[x][0]]);
if(son[x][1])umin(mi[x],mi[son[x][1]]),umax(ma[x],ma[son[x][1]]);
}
inline void rotate(int x){
int y=f[x],w=son[y][1]==x;
son[y][w]=son[x][w^1];
if(son[x][w^1])f[son[x][w^1]]=y;
if(f[y]){
int z=f[y];
if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
}
f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
}
inline void splay(int x){
int s=1,i=x,y;a[1]=i;
while(!isroot(i))a[++s]=i=f[i];
while(s)pb(a[s--]);
while(!isroot(x)){
y=f[x];
if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
rotate(x);
}
up(x);
}
inline void cut(int x){
splay(x);
if(son[x][0])f[son[x][0]]=f[x];
son[x][0]=0;
up(x);
}
inline void access(int x){
for(int y=0;x;y=x,x=f[x]){
splay(x);
son[x][1]=0;
up(x);
modify(vis[x],ml[pre[mi[x]]]+1,ma[x]);
tag1(x,n);
son[x][1]=y;
up(x);
}
}
}
inline void ext(int w){
++n;
RT[n]=RT[n-1],T[n]=T[n-1];
int p=++tot,x=last,r,q;
for(ml[last=p]=ml[x]+1;x&&!son[x][w];x=pre[x])son[x][w]=p;
if(!x)pre[p]=1;
else if(ml[x]+1==ml[q=son[x][w]])pre[p]=q;
else{
pre[r=++tot]=pre[q];memcpy(son[r],son[q],sizeof son[r]);
ml[r]=ml[x]+1;
LCT::up(r);
LCT::splay(q);
LCT::vis[r]=LCT::vis[q];
LCT::f[r]=pre[q];
LCT::cut(q);
LCT::f[q]=r;
pre[p]=pre[q]=r;
for(;x&&son[x][w]==q;x=pre[x])son[x][w]=r;
}
LCT::up(p);
LCT::f[p]=pre[p];
LCT::access(p);
}
int main(){
scanf("%s",a+1);
m=strlen(a+1);
for(i=1;i<=m;i++)ext(a[i]-'a');
scanf("%d",&m);
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%s",a);
x=a[0]-'a';
x=((x+ans)%26+26)%26;
ext(x);
}else{
scanf("%d%d",&x,&y);
x=((x-1+ans)%n+n)%n+1;
y=((y-1+ans)%n+n)%n+1;
if(x>y)swap(x,y);
printf("%d\n",ans=max(ask(RT[y],1,100000,x,y),cal(T[y],1,100000,x)-x+1));
}
}
return 0;
}

  

BZOJ4963 : String的更多相关文章

  1. 透过WinDBG的视角看String

    摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...

  2. JavaScript String对象

    本编主要介绍String 字符串对象. 目录 1. 介绍:阐述 String 对象的说明以及定义方式. 2. 实例属性:介绍 String 对象的实例属性: length. 3. 实例方法:介绍 St ...

  3. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  4. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密

    string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...

  5. js报错: Uncaught RangeError: Invalid string length

    在ajax请求后得到的json数据,遍历的时候chrome控制台报这个错误:Uncaught RangeError: Invalid string length,在stackoverflow查找答案时 ...

  6. c# 字符串连接使用“+”和string.format格式化两种方式

    参考文章:http://www.liangshunet.com/ca/201303/218815742.htm 字符串之间的连接常用的两种是:“+”连接.string.format格式化连接.Stri ...

  7. 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed

    之前以为BinaryWriter写string会严格按构造时指定的编码(不指定则是无BOM的UTF8)写入string的二进制,如下面的代码: //将字符串"a"写入流,再拿到流的 ...

  8. JavaScript中String对象的方法介绍

    1.字符方法 1.1 charAt() 方法,返回字符串中指定位置的字符. var question = "Do you like JavaScript?"; alert(ques ...

  9. 在多线程编程中lock(string){...}隐藏的机关

    常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...

随机推荐

  1. 常见的爬虫分析库(2)-xpath语法

    xpath简介 1.xpath使用路径表达式在xml和html中进行导航 2.xpath包含标准函数库 3.xpath是一个w3c的标准 xpath节点关系 1.父节点 2.子节点 3.同胞节点 4. ...

  2. WCF 非http寄宿IIS

    摘要 从IIS 7 开始, IIS增加了对非HTTP协议的支持. 因此, 自IIS 7之后, 可以将NetTcpBinding等非HTTP协议的Bindings直接寄宿在IIS上面. 本文将介绍如何在 ...

  3. Git强制拉取覆盖本地

    1.多条执行 git fetch --all git reset --hard origin/master git pull 2.单条执行 git fetch --all && git ...

  4. RPC服务超时排查思路

    RPC服务超时排查思路- 1.查看服务提供者日志相关信息进行排查- 2.查看消费者的超时时间设置是否合理- 3.查看服务提供者业务逻辑是否有DB操作,有的话看是否有慢SQL- 4.查看服务提供者业务逻 ...

  5. redis centos 6.5 redis版本3.2.8安装过程

    redis作为非关系数据库的典型应用,在庞大的数据通信处理有着自己强大的优势,今天也自己来开始学些redis. 以下每一个语句都是我执行的命令. 按照所查资料分析,需要tcl测试工具,这个在cento ...

  6. net core体系-web应用程序-4net core2.0大白话带你入门-2asp.net core新建项目

    新建asp.net core项目   开发环境:Windows Server R2 2008 开发工具:Microsoft Visual Studio 2017 新建asp.net core项目 创建 ...

  7. squid,nginx,lighttpd反向代理的区别

    反向代理从传输上分可以分为2种: 1:同步模式(apache-mod_proxy和squid) 2:异步模式(lighttpd 和 nginx) 在nginx的文档说明中,提到了异步传输模式并提到它可 ...

  8. HDU4466 Triangle 计数 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/HDU4466.html 题目传送门 - HDU4466 题意 多组数据,每次询问一个数 $n(n\leq 5\t ...

  9. POJ3041 Asteroids 二分图匹配 匈牙利算法

    原文链接http://www.cnblogs.com/zhouzhendong/p/8229200.html 题目传送门 - POJ3041 题意概括 有一个n*n的矩阵,有些点是障碍物. 现在每次可 ...

  10. 【目录】《剑指Offer》Java实现

    如题: 1) 找出数组中重复的数字 2) 不修改数组找出重复的数字 3) 二维数组中的查找 4) 替换空格 5) 从尾到头打印链表 6) 重建二叉树 7) 二叉树的下一个结点 8) 用两个栈实现队列 ...