BZOJ2120 数颜色

分析

一篇博客
带修莫队模板题。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#pragma GCC optimize ("O3")
using namespace std;
template<class T> inline T read(T&x){
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=1e4+7,MAXC=1e6+7;

int n,m,B;
int ql=1,qr=0,cur,res;
int ans[MAXN],a[MAXN],cnt[MAXC];

int idxC,idxQ,tim[MAXN],pos[MAXN],val[MAXN],pre[MAXN];

inline int bl(int x)
{
    return (x-1)/B+1;
}

struct query
{
    int id,tim,l,r;
    bool operator<(const query&x)const
    {
        if(bl(l)^bl(x.l))
            return l<x.l;
        else if(bl(r)^bl(x.r))
            return r<x.r;
        else
            return tim<x.tim;
    }
}q[MAXN];

inline void change_add(int cur)
{
    if(ql<=pos[cur]&&pos[cur]<=qr)
    {
        --cnt[a[pos[cur]]];
        if(!cnt[a[pos[cur]]])
            --res;
    }
    pre[cur]=a[pos[cur]];
    a[pos[cur]]=val[cur];
    if(ql<=pos[cur]&&pos[cur]<=qr)
    {
        if(!cnt[a[pos[cur]]])
            ++res;
        ++cnt[a[pos[cur]]];
    }
}

inline void change_del(int cur)
{
    if(ql<=pos[cur]&&pos[cur]<=qr)
    {
        --cnt[a[pos[cur]]];
        if(!cnt[a[pos[cur]]])
            --res;
    }
    a[pos[cur]]=pre[cur];
    if(ql<=pos[cur]&&pos[cur]<=qr)
    {
        if(!cnt[a[pos[cur]]])
            ++res;
        ++cnt[a[pos[cur]]];
    }
}

inline void change(int now)
{
    while(cur<idxC&&tim[cur+1]<=now)
        change_add(++cur);
    while(cur&&tim[cur]>now)
        change_del(cur--);
}

inline void add(int p)
{
    if(!cnt[a[p]])
        ++res;
    ++cnt[a[p]];
}

inline void del(int p)
{
    --cnt[a[p]];
    if(!cnt[a[p]])
        --res;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);read(m);
    B=pow(n,2.0/3);
    for(rg int i=1;i<=n;++i)
        read(a[i]);
    for(rg int i=1;i<=m;++i)
    {
        char opt[2];
        scanf("%s",opt);
        if(opt[0]=='Q')
        {
            ++idxQ;
            q[idxQ].id=idxQ,q[idxQ].tim=i;
            read(q[idxQ].l);read(q[idxQ].r);
        }
        else if(opt[0]=='R')
        {
            tim[++idxC]=i;
            read(pos[idxC]);
            read(val[idxC]);
        }
    }
    sort(q+1,q+idxQ+1);
    for(rg int i=1;i<=idxQ;++i)
    {
        change(q[i].tim);
        while(ql>q[i].l)
            add(--ql);
        while(qr<q[i].r)
            add(++qr);
        while(ql<q[i].l)
            del(ql++);
        while(qr>q[i].r)
            del(qr--);
        ans[q[i].id]=res;
    }
    for(rg int i=1;i<=idxQ;++i)
        printf("%d\n",ans[i]);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/9545886.html