zoukankan      html  css  js  c++  java
  • 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('
    '); }
    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;
    }
  • 相关阅读:
    js canvas游戏初级demo-上下左右移动
    js java 给定一个目标值,在一棵树中找是否有两个节点的值之和等于目标值
    mysql ON DUPLICATE KEY UPDATE 与 REPLACE INTO 的区别
    js canvas获取图片base64 dataUrl
    一次安卓单机游戏修改经历...
    nodejs 使用superagent+cheerio+eventproxy爬取豆瓣帖子
    express 随笔
    阿里云入坑指南&&nodejs 安装配置
    js 利用jquery.gridly.js实现拖拽并且排序
    js 日期格式化
  • 原文地址:https://www.cnblogs.com/rrsb/p/8666176.html
Copyright © 2011-2022 走看看