bzoj 2120: 数颜色带修改莫队

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2120: 数颜色带修改莫队相关的知识,希望对你有一定的参考价值。

比较裸的带修莫队,对每个修改操作记一下它修改的位置修改前的颜色
然后正常莫队,每次对修改操作时间倒流一下即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=200005;
int n,m,bl[N],la[N],co[1000005],ta,tb,v[N],con[1000005],ans[N],nw;
char s[10];
struct qw
{
    int p,c,pr;
}a[N];
struct qwe
{
    int l,r,id,ti;
}b[N];
bool cmp(const qwe &a,const qwe &b)
{
    return bl[a.l]<bl[b.l]||(bl[a.l]==bl[b.l]&&a.r<b.r);
}
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
void clc(int x)
{
    if(v[x])
    {
        if(!--con[co[x]])
            nw--;
    }
    else if(++con[co[x]]==1)
        nw++;
    v[x]^=1;
}
void change(int x,int c)
{
    if(v[x])
    {
        clc(x);
        co[x]=c;
        clc(x);
    }
    else
        co[x]=c;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        la[i]=co[i]=read();
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        int x=read(),y=read();
        if(s[0]==‘R‘)
        {
            a[++ta].p=x;
            a[ta].c=y;
            a[ta].pr=la[x];//记录更改之前的颜色
            la[x]=y;
        }
        else
        {
            b[++tb].l=x;
            b[tb].r=y;
            b[tb].id=tb;
            b[tb].ti=ta;//记录他之前的离他最近的操作
        }
    }
    int kuai=sqrt(n);
    for(int i=1;i<=n;i++)
        bl[i]=(i-1)/kuai+1;
    sort(b+1,b+tb+1,cmp);
    int l=1,r=1;
    clc(l);
    for(int i=1;i<=tb;i++)
    {
        for(int j=b[i-1].ti+1;j<=b[i].ti;j++)
            change(a[j].p,a[j].c);
        for(int j=b[i-1].ti;j>b[i].ti;j--)
            change(a[j].p,a[j].pr);
        while(l<b[i].l)  
            clc(l++);
        while(l>b[i].l)  
            clc(--l);
        while(r<b[i].r)  
            clc(++r);
        while(r>b[i].r)  
            clc(r--);
        ans[b[i].id]=nw;
    }
    for(int i=1;i<=tb;i++)
        printf("%d
",ans[i]);
    return 0;
}

以上是关于bzoj 2120: 数颜色带修改莫队的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2120: 数颜色带修改莫队

BZOJ2120数颜色(带修改莫队)

bzoj2120: 数颜色(带修改的莫队)

bzoj2120 数颜色 莫队 带修改

[国家集训队][bzoj2120] 数颜色 [带修改莫队]

BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树