• P1903 [国家集训队]数颜色 / 维护队列


    思路

    带修莫队的板子

    带修莫队只需要多维护一个时间的指针即可,记录一下每个询问在第几次修改之后,再回退或者前进几个修改操作

    排序的时候如果a.l和b.l在一个块里,就看r,如果a.r和b.r在一个块里,就看t

    然后块的大小(O(n^{frac{2}{3} }))最优,时间复杂度是(O(n^{frac{5}{3}}))

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    struct Oper{
        int pos,from,to;
    }M[50010];
    struct Ask{
        int l,r,tim,id;
    }Q[50010];
    int L,R,T,barrel[1000100],ans,arr[50010],a[50010];
    int n,m,siz,num,be[50010],out[50010];
    bool cmp(Ask a,Ask b){
        return ((be[a.l]==be[b.l])?(be[a.r]==be[b.r]?a.tim<b.tim:be[a.r]<be[b.r]):be[a.l]<be[b.l]);
    }
    void going(int t,int opt){
        if(opt==1){
            arr[M[t].pos]=M[t].to;
            if(M[t].pos>=L&&M[t].pos<=R){
                barrel[M[t].from]--;
                if(!barrel[M[t].from])
                    ans--;
                if(!barrel[M[t].to])
                    ans++;
                barrel[M[t].to]++;
            }
        }
        else{
            arr[M[t].pos]=M[t].from;
            if(M[t].pos>=L&&M[t].pos<=R){
                barrel[M[t].to]--;
                if(!barrel[M[t].to])
                    ans--;
                if(!barrel[M[t].from])
                    ans++;
                barrel[M[t].from]++;
            }
        }
        T+=opt;
    }
    void movel(int opt){
        if(opt==1){
            barrel[arr[L]]--;
            if(!barrel[arr[L]])
                ans--;
        }
        else{
            if(!barrel[arr[L-1]])
                ans++;
            barrel[arr[L-1]]++;
        }
        L+=opt;
    }
    void mover(int opt){
        if(opt==1){
            if(!barrel[arr[R+1]])
                ans++;
            barrel[arr[R+1]]++;
        }
        else{
            barrel[arr[R]]--;
            if(!barrel[arr[R]])
                ans--;
        }
        R+=opt;
    }
    void calbe(void){
        siz=pow(n,0.6666666666);
        num=n/siz;
        if(n%siz)
            num++;
        for(int i=1;i<=n;i++)
            be[i]=i/siz+1;  
    }
    int main(){
        scanf("%d %d",&n,&m);
        int cnt=0,anscnt=0;;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),arr[i]=a[i];
        L=R=T=0;
        for(int i=1;i<=m;i++){
            char opt=getchar();
            while(opt!='R'&&opt!='Q')
                opt=getchar();
            if(opt=='R'){
                ++cnt;
                scanf("%d %d",&M[cnt].pos,&M[cnt].to);
                M[cnt].from=a[M[cnt].pos];
                a[M[cnt].pos]=M[cnt].to;
            }
            else{
                ++anscnt;
                Q[anscnt].id=anscnt;
                scanf("%d %d",&Q[anscnt].l,&Q[anscnt].r);
                Q[anscnt].tim=cnt;
            }
        }
        calbe();
        sort(Q+1,Q+anscnt+1,cmp);
        for(int i=1;i<=anscnt;i++){
            while(T<Q[i].tim)
                going(T+1,1);
            while(T>Q[i].tim)
                going(T,-1);
            while(L<Q[i].l)
                movel(1);
            while(L>Q[i].l)
                movel(-1);
            while(R<Q[i].r)
                mover(1);
            while(R>Q[i].r)
                mover(-1);
            out[Q[i].id]=ans;
        }
        for(int i=1;i<=anscnt;i++)
            printf("%d
    ",out[i]);
        return 0;
    }
    
  • 相关阅读:
    多层开发的小知识
    DIV+CSS基础教程:导航条的制作详解
    JavaScript函数
    css:学习CSS了解单位em和px的区别
    blank开新窗口为什么通不过W3C验证
    对javascript匿名函数的理解(透彻版)
    .net如何与windows身份验证的sql数据库连接
    Aptana2.0系列教程
    C# Tostring() 格式大全
    类关系图
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10669347.html
Copyright © 2020-2023  润新知