对于一个周期长度$p$来说,如果它不是$S_k$的周期,那么它一定不是$S_{k+1}$的周期,因此可以二分出分界线$t_p$满足它是$S_p,S_{p+1},S_{p+2},\dots,S_{t_p}$的周期,但不是$S_{t_p+1}$的周期。对于一个询问$(k,l,r)$,问题等价于寻找区间中数值最小的数,满足它的$t$值至少为$k$。将所有询问按$k$从大到小排序,并将所有周期按$t$值从大到小排序,用线段树支持单点修改、区间查询最小值即可。
时间复杂度$\mathcal{O}(n\log n)$。
#include<cstdio> const int BUF=20000000; char Buf[BUF],*buf=Buf; inline void readch(char&a){for(;!((*buf>='a'&&*buf<='z')||(*buf>='A'&&*buf<='Z'));buf++);a=*buf++;} inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} const int OUT=4000000; char Out[OUT],*ou=Out;int Outn[30],Outcnt; inline void write(int x){ if(x<0){ *ou++='-'; x*=-1; } if(!x)*ou++=48; else{ for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48; while(Outcnt)*ou++=Outn[Outcnt--]; } } inline void writeln(int x){write(x);*ou++='\n';} const int N=500005,S1=13331,P1=1000000007,S2=233,P2=1000000009; int n,m,q,i,j,x,y,f[N],st[N],head,tail,cur,que[N][2],ans[N],pos[N],v[1111111]; int p1[N],h1[N*2],p2[N],h2[N*2]; char a[N*2]; int e[N],w[N],nxt[N]; int g[N],nxtq[N]; inline int geth1(int l,int r){return((h1[r]-1LL*h1[l-1]*p1[r-l+1])%P1+P1)%P1;} inline int geth2(int l,int r){return((h2[r]-1LL*h2[l-1]*p2[r-l+1])%P2+P2)%P2;} inline int getper(int x){ int l=x+1,r=n,mid,t=x; while(l<=r){ mid=(l+r)>>1; int L=st[mid],R=L+mid-1; if(geth1(L,R-x)==geth1(L+x,R)&&geth2(L,R-x)==geth2(L+x,R))l=(t=mid)+1;else r=mid-1; } return t; } inline void up(int&a,int b){a>b?(a=b):0;} void build(int x,int a,int b){ v[x]=N; if(a==b){ pos[a]=x; return; } int mid=(a+b)>>1; build(x<<1,a,mid),build(x<<1|1,mid+1,b); } inline void ins(int x,int p){for(x=pos[x];x;x>>=1)up(v[x],p);} void ask(int x,int a,int b,int c,int d){ if(c<=a&&b<=d){ up(cur,v[x]); return; } int mid=(a+b)>>1; if(c<=mid)ask(x<<1,a,mid,c,d); if(d>mid)ask(x<<1|1,mid+1,b,c,d); } int main(){ fread(Buf,1,BUF,stdin); read(n); head=n+1; tail=n; for(i=1;i<=n;i++){ char op; readch(op); if(op>='a'&&op<='z')a[--head]=op; else a[++tail]=op-'A'+'a'; st[i]=head; } for(p1[0]=i=1;i<=n;i++)p1[i]=1LL*p1[i-1]*S1%P1; for(i=head;i<=tail;i++)h1[i]=(1LL*h1[i-1]*S1+a[i])%P1; for(p2[0]=i=1;i<=n;i++)p2[i]=1LL*p2[i-1]*S2%P2; for(i=head;i<=tail;i++)h2[i]=(1LL*h2[i-1]*S2+a[i])%P2; for(i=1;i<=n;i++)f[i]=getper(i); read(m); for(i=1;i<=m;i++){ read(x); y=f[x]; w[i]=x; nxt[i]=e[y]; e[y]=i; } read(q); for(i=1;i<=q;i++){ read(x);read(que[i][0]);read(que[i][1]); nxtq[i]=g[x]; g[x]=i; } build(1,1,m); for(i=n;i;i--){ for(j=e[i];j;j=nxt[j])ins(j,w[j]); for(j=g[i];j;j=nxtq[j]){ cur=N; ask(1,1,m,que[j][0],que[j][1]); if(cur>i)cur=-1; ans[j]=cur; } } for(i=1;i<=q;i++)writeln(ans[i]); fwrite(Out,1,ou-Out,stdout); }
- Periodicity Regionals Contest Problem Onlineperiodicity regionals contest problem regionals contest online 2022 regionals contest online 2023 regionals contest online mdielk regionals contest online string regionals游记contest online regionals multiply contest problem regionals contest online abefj contest problem 20035 http codeforces contest problem 1553