对询问扫描线,建出 \(PAM\) 的失配树之后,每次查询相当于,把 \(r\) 对应节点到根路径染色之后,有多少个节点的值大于 \(l\),可以树剖+ODT 实现
code
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define N 400005
#define pii pair<int,int>
#define fir first
#define sec second
int n,m;
int pos[N];
char a[N];
vector<int> G[N];
namespace PAM{
int tot,las;
int len[N],f[N],ch[N][27];
int nw(int l){
len[++tot]=l,f[tot]=0;
return tot;
}
void pre(){
tot=-1,las=0,a[0]='#';
nw(0),nw(-1),f[0]=1;
}
int gt_f(int p,int i){
while(a[i-len[p]-1]!=a[i]) p=f[p];
return p;
}
void ins(int c,int i){
int p=gt_f(las,i);
if(!ch[p][c]){
int q=nw(len[p]+2);
f[q]=ch[gt_f(f[p],i)][c];
ch[p][c]=q;
}
las=ch[p][c],pos[i]=las;
}
void build(){
for(int i=2;i<=tot;i++){
if(!f[i]) f[i]=1;
G[f[i]].push_back(i);
}
}
}
int tot;
int sz[N],son[N],tp[N],dfn[N],fu[N];
void dfs1(int x,int fa){
sz[x]=1;
for(auto y:G[x]){
if(y==fa) continue;
dfs1(y,x);sz[x]+=sz[y];
if(sz[son[x]]<sz[y]) son[x]=y;
}
}
struct A{
int l,r,col;
};
bool operator < (A x,A y){
if(x.l!=y.l) return x.l<y.l;
return x.r<y.r;
}
set<A> q[N];
void dfs2(int x,int fa,int top){
//printf("%d %d %d\n",x,fa,top);
dfn[x]=++tot,tp[x]=top,fu[x]=fa;
if(son[x]) dfs2(son[x],x,top);
else q[top].insert({dfn[top],dfn[x],0});
for(auto y:G[x]){
if(y==fa||y==son[x]) continue;
dfs2(y,x,y);
}
}
int c[N];
inline int lowbit(int x){
return x&(-x);
}
void add(int x,int y){
if(!x) return ;
for(;x;x-=lowbit(x)) c[x]+=y;
}
int sum(int x){
int ans=0;
for(;x<=n;x+=lowbit(x)) ans+=c[x];
return ans;
}
void gai(int id,int x,int y){
while(1){
auto it=q[id].begin();
A p=*it;
if(p.r>=x){
add(p.col,-(x-p.l+1));q[id].erase(it);
if(p.r>x) q[id].insert({x+1,p.r,p.col});
break;
}
add(p.col,-(p.r-p.l+1)),q[id].erase(it);
}
add(y,x-dfn[id]+1);
q[id].insert({dfn[id],x,y});
}
void upd(int x,int y){
while(x){
gai(tp[x],dfn[x],y);
x=fu[tp[x]];
}
}
int ans[N];
vector<pii > qry[N];
inline int read(){
int num=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while('0'<=c&&c<='9') num=num*10+c-'0',c=getchar();
return num;
}
int main(){
freopen("necklace.in","r",stdin);
freopen("necklace.out","w",stdout);
scanf("%s",a+1);
n=strlen(a+1);
scanf("%d",&m);
for(int i=1,x,y;i<=m;i++){
x=read(),y=read();
qry[y].push_back({x,i});
}
PAM::pre();
for(int i=1;i<=n;i++) PAM::ins(a[i]-'a'+1,i);
PAM::build();
dfs1(1,0),dfs2(1,0,1);
for(int i=1;i<=n;i++){
upd(pos[i],i);
for(auto p:qry[i]) ans[p.sec]=sum(p.fir)-1;
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
标签:2024.2,int,题解,top,T2,tot,id,dfn,void
From: https://www.cnblogs.com/hubingshan/p/18035599