Noi 十连测 基因改造计划
SOL:
我们跑马拉车算法,然后写主席树维护。
#include<bits/stdc++.h> #define LL long long #define M 6000007 #define N 260010 #define Mid (l+r>>1) using namespace std; LL allsf,allsi,allcnt; int n,m; #define sight(c) ('0'<=c&&c<='9') inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } struct Tree{ struct Node{ int lc,rc,cnt; LL sf,si; }T[M]; int rot[N],tot; int x,f,i,L,R; void add(int past,int &now,int l,int r) { now=++tot; T[now]=T[past]; T[now].sf+=f; T[now].si+=i; T[now].cnt++; if (l==r) return; if (x<=Mid) add(T[past].lc,T[now].lc,l,Mid); else add(T[past].rc,T[now].rc,Mid+1,r); } void que(int past,int now,int l,int r){ if (L<=l&&r<=R) { allsf+=(T[now].sf-T[past].sf); allsi+=T[now].si-T[past].si; allcnt+=T[now].cnt-T[past].cnt; return; } if (L<=Mid) que(T[past].lc,T[now].lc,l,Mid); if (R> Mid) que(T[past].rc,T[now].rc,Mid+1,r); } void adds(int now,int X,int F,int I){ x=min(X,n+1); f=F; i=I; add(rot[now-1],rot[now],0,n+1); } void ques(int l,int r,int LLL,int RR){ allsf=allsi=allcnt=0; L=LLL; R=RR; que(rot[l-1],rot[r],0,n+1); } }T1,T2; char s[N],ch[N]; int f[N],k=1,l,r; LL ans; void mach(){ for (int i=n;i;i--) s[i<<1]=ch[i],s[i*2-1]='&'; n=n<<1|1; s[n]='&'; s[0]='{'; f[1]=0; for (int i=2;i<=n;i++) { if (k+f[k]>=i) f[i]=min(k+f[k]-i,f[2*k-i]); else f[i]=-1; while(s[i+f[i]+1]==s[i-f[i]-1]) ++f[i]; if(i+f[i]>=k+f[k]) k=i; } for(int i=1;i<=n;++i){ T1.adds(i,i-f[i],f[i],i); T2.adds(i,i+f[i],f[i],i); } } signed main () { // freopen() freopen("gene.in","r",stdin); freopen("gene.out","w",stdout); read(n); read(m); scanf("%s",ch+1); mach(); while (m--){ read(l); read(r); ans=r-l+1; l=l*2-1; r=r<<1|1; T1.ques(l,Mid,0,l); ans+=allsi-l*allcnt; // writel(allsi); writel(allcnt); // writeln(ans); T1.ques(l,Mid,l+1,n+1); ans+=allsf; T2.ques(Mid+1,r,0,r); ans+=allsf; T2.ques(Mid+1,r,r+1,n+1); ans+=r*allcnt-allsi; writeln(ans>>1); } return 0; }