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;
}

 

posted @ 2018-03-28 20:46  泪寒之雪  阅读(239)  评论(0编辑  收藏  举报