传送门
题解:
其实和BZOJ5384是同一个东西,只需要把区间加用主席树维护一下就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;
while(!isdigit(c=gc()));T num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline int getint(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs int N=1e5+5;
int n,q,op;
char s[N];
namespace PAM{
int son[N][26],fa[N],len[N],last,now;
int up[N],d[N];
int in[N],out[N],clk;
std::vector<int> G[N];
inline void init(){fa[0]=1,len[1]=-1,now=1;}
inline void push_back(char c,int i){c-='a';
int p=last;
while(s[i]!=s[i-len[p]-1])p=fa[p];
if(!son[p][c]){
len[++now]=len[p]+2;
int k=fa[p];
while(s[i]!=s[i-len[k]-1])k=fa[k];
fa[now]=son[k][c],son[p][c]=now;
d[now]=len[now]-len[fa[now]];
up[now]=d[now]==d[fa[now]]?up[fa[now]]:now;
}
last=son[p][c];
}
void dfs(int u){
in[u]=++clk;
for(int re v:G[u])dfs(v);
out[u]=clk;
}
inline void build(){
for(int re i=0;i<=now;++i)if(i!=1)G[fa[i]].push_back(i);
dfs(1);
}
}
namespace SGT{
int a[N<<2],M;
inline void build(int n){for(M=1;M<n;M<<=1);}
inline void update(int p,int v){
for(a[p+=M]=v,p>>=1;p;p>>=1)a[p]=std::max(a[p<<1],a[p<<1|1]);
}
inline int query(int l,int r){
int ans=0;
for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
if(l&1^1)ans=std::max(ans,a[l^1]);
if(r&1) ans=std::max(ans,a[r^1]);
}
return ans;
}
}
int rt[N];
namespace PST{
cs int N=::N*300;
int lc[N],rc[N],tag[N],now;
inline int newnode(int u){
int k=++now;
if(u)lc[k]=lc[u],rc[k]=rc[u],tag[k]=tag[u];
return k;
}
inline void add(int &rt,int l,int r,int ql,int qr){
rt=newnode(rt);
if(ql<=l&&r<=qr){++tag[rt];return ;}
int mid=l+r>>1;
if(ql<=mid)add(lc[rt],l,mid,ql,qr);
if(mid<qr)add(rc[rt],mid+1,r,ql,qr);
}
inline int query(int rt,int l,int r,int p){
if(l==r)return tag[rt];
int mid=l+r>>1;
return tag[rt]+(p<=mid?query(lc[rt],l,mid,p):query(rc[rt],mid+1,r,p));
}
}
signed main(){
// freopen("gene.in","r",stdin);//freopen("gene.out","w",stdout);
scanf("%d%d%d",&op,&n,&q);
scanf("%s",s+1);s[0]=255;PAM::init();
for(int re i=1;i<=n;++i)PAM::push_back(s[i],i);
PAM::build();
int now=1;SGT::build(PAM::clk);
for(int re i=1;i<=n;++i){
rt[i]=rt[i-1];
while(s[i]!=s[i-PAM::len[now]-1])now=PAM::fa[now];
now=PAM::son[now][s[i]-'a'];
for(int re x=now;x;x=PAM::fa[PAM::up[x]]){
int tmp=SGT::query(PAM::in[x],PAM::out[x]);
int l=std::max(1,tmp-PAM::len[x]+2);
int r=i-PAM::len[PAM::up[x]]+1;
PST::add(rt[i],1,n,l,r);
}
SGT::update(PAM::in[now],i);
}
int ans=0;
while(q--){
int l=getint()^(op?ans:0),r=getint()^(op?ans:0);
cout<<(ans=PST::query(rt[r],1,n,l))<<"\n";
}
return 0;
}