【BZOJ 2120】带修莫队

BZOJ 2120
裸的带修莫队
带修莫队对莫队来说 主要有几点变化 首先分的块是n^(1.5)
这样总时间复杂度是O(n^(5/3))
然后解决修改的问题就是加一个时间变量
先解决时间维度 对这次提问 如果在你修改之后 那么你把需要的都修改上
如果在你修改之前 那么你把需要的都加回来
其他是和莫队一样的l r顺序

/*
BZOJ 2120
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int MAX_N = 50024;
int ans[MAX_N],flag[1000024],col[MAX_N],pos[MAX_N],lst[MAX_N];
struct node {int l,r,id,pos,k;}Q[MAX_N];
struct opti {int l,r,z;}o[MAX_N];
int L = 1 ,R = 0,Ans = 0,K = 0,q_num,o_num;
bool cmp (const node &a,const node &b){
    if(pos[a.l]^pos[b.l]) return pos[a.l]<pos[b.l];
    if(pos[a.r]^pos[b.r]) return pos[a.r]<pos[b.r];
    return a.k<b.k;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int blo = pow(n,2.0/3);
    for(int i = 1;i<=n;++i){
        scanf("%d",&col[i]);
        pos[i] = i / blo;
        lst[i] = col[i];
    }
    char str[20];
    int x,y;
    for(int i = 1;i<=m;++i){
        scanf("%s%d%d",str,&x,&y);
        if(str[0]!='R'){
            Q[++q_num].l = x,Q[q_num].r = y,Q[q_num].pos = q_num,Q[q_num].k = o_num;
        }
        else {
            o[++o_num].l = x,o[o_num].r = y,o[o_num].z = lst[x],lst[x] = y;
        }
    }
    sort(Q+1,Q+1+q_num,cmp);
    for(int i = 1;i<=q_num;i++){
    while(K<Q[i].k){
        ++K;
        if(L<=o[K].l&&o[K].l<=R){
        if(!--flag[col[o[K].l]]) Ans--;
        if(!flag[o[K].r]++) Ans++;
        }
        col[o[K].l] = o[K].r;
    }
    while(K>Q[i].k){
        if(L<=o[K].l&&o[K].l<=R){
        if(!--flag[col[o[K].l]]) Ans--;
        if(!flag[o[K].z]++) Ans++;
        }
        col[o[K].l] = o[K].z;
        --K;
    }
    while(R<Q[i].r){
        R++;
        if(!flag[col[R]]++) Ans++;
    }
    while(L>Q[i].l){
        L--;
        if(!flag[col[L]]++) Ans++;
    }
    while(L<Q[i].l){
        if(!--flag[col[L]]) Ans--;
        L++;
    }
    while(R>Q[i].r){
        if(!--flag[col[R]]) Ans--;
        R--;
    }
    ans[Q[i].pos] = Ans;
    }
    for(int i = 1;i<=q_num;++i)
        printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/89338714
今日推荐