zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    JD笔试试题(凭记忆写的+人生感悟 try finally )
    ZOJ 3626 Treasure Hunt I(树形dp)
    Oracle数据库有用函数
    leetcode
    BIEE11G系统数据源账号过期问题(默认安装步骤)
    class文件结构浅析(2)
    使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量
    Linux基本配置和管理 3 ---- Linux命令行文本处理工具
    android面试题及答案
    CentOS 6.4的安装--史上最全-CRPER木木
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10669347.html
Copyright © 2011-2022 走看看