# 封印

$n\leq 2\times 10^5$

## 题解

https://www.cnblogs.com/dysyn1314/p/13158865.html

• 对于$R[i]\leq r$$i$，相当于询问$\max_{l\leq i\leq r}\{R[i]-i+1\}$

• 对于$R[i]>r$$i$，相当于询问$r+\max_{l\leq i\leq r}\{-i\}+1$

CO int N=4e5+10,inf=1e9;
namespace SAM{
int last=1,tot=1;
array<int,26> ch[N];
int fa[N],len[N];

void extend(int c){
int x=last,cur=last=++tot;
len[cur]=len[x]+1;
for(;x and !ch[x][c];x=fa[x]) ch[x][c]=cur;
if(!x) {fa[cur]=1; return;}
int y=ch[x][c];
if(len[y]==len[x]+1) {fa[cur]=y; return;}
int clone=++tot;
ch[clone]=ch[y],fa[clone]=fa[y],len[clone]=len[x]+1;
fa[cur]=fa[y]=clone;
for(;ch[x][c]==y;x=fa[x]) ch[x][c]=clone;
}
}

struct SEG{
int tree[2*N];

#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
IN void push_up(int x){
tree[x]=max(tree[lc],tree[rc]);
}
void build(int x,int l,int r,int v[N]){
if(l==r) {tree[x]=v[l]; return;}
build(lc,l,mid,v);
build(rc,mid+1,r,v);
push_up(x);
}
void insert(int x,int l,int r,int p,int v){
if(l==r) {tree[x]=v; return;}
if(p<=mid) insert(lc,l,mid,p,v);
else insert(rc,mid+1,r,p,v);
push_up(x);
}
int query(int x,int l,int r,int ql,int qr){
if(ql<=l and r<=qr) return tree[x];
if(qr<=mid) return query(lc,l,mid,ql,qr);
if(ql>mid) return query(rc,mid+1,r,ql,qr);
return max(query(lc,l,mid,ql,qr),query(rc,mid+1,r,ql,qr));
}
#undef lc
#undef rc
#undef mid
}T1,T2;

char s[N],t[N];
int R[N],ans[N];
struct event {int l,r,id;} e[N];

int main(){
scanf("%s%s",s+1,t+1);
int n=strlen(s+1),m=strlen(t+1);
for(int i=1;i<=m;++i) SAM::extend(t[i]-'a');
int num=0;
for(int i=1,x=1;i<=n;++i){
using namespace SAM;
R[i]=max(R[i-1],i-1);
if(R[i]==i-1) x=1;
for(;x!=1 and len[fa[x]]+1>R[i]-i+1;x=fa[x]);
for(;R[i]+1<=n and ch[x][s[R[i]+1]-'a'];x=ch[x][s[R[i]+1]-'a'],++R[i]);
e[++num]={i,R[i],0};
}
for(int i=1;i<=q;++i){
e[++num]={l,r,i};
}
static int tmp[N];
for(int i=1;i<=n;++i) tmp[i]=-inf;
T1.build(1,1,n,tmp);
for(int i=1;i<=n;++i) tmp[i]=-i;
T2.build(1,1,n,tmp);
sort(e+1,e+num+1,[&](CO event&a,CO event&b)->bool{
return a.r!=b.r?a.r<b.r:a.id<b.id;
});
for(int i=1;i<=num;++i){
if(!e[i].id){
T1.insert(1,1,n,e[i].l,e[i].r-e[i].l+1);
T2.insert(1,1,n,e[i].l,-inf);
}
else{
int x=T1.query(1,1,n,e[i].l,e[i].r);
int y=e[i].r+T2.query(1,1,n,e[i].l,e[i].r)+1;
ans[e[i].id]=max(x,y);
}
}
for(int i=1;i<=q;++i) printf("%d\n",ans[i]);
return 0;
}


posted on 2020-07-05 20:30  autoint  阅读(68)  评论(0编辑  收藏