bzoj2120: 数颜色

Posted AKCqhzdy

tags:

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

这题其实可以用更加高级的东西做,但是我为了学带修莫队(优雅的打暴力)就用这个做了。

相较于莫队,带修莫队需要多维护一个东西——时间。怎么维护?想想l,r的维护方式(笑)当然就是暴力啦!

对于当前位置当前时间,保存他上一个颜色和下一个颜色,在普通莫队之前先将时间暴力解决,然后就和普通莫队无异了。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct Query
{
    int l,r,T,id;
}q[11000];int qlen;
struct Change
{
    int x,be,af;
}c[11000];int clen,last[11000];
int st[11000];
bool cmp(Query a,Query b)
{
    if( st[a.l]<st[b.l] || 
        (st[a.l]==st[b.l]&&st[a.r]<st[b.r]) ||
            (st[a.l]==st[b.l]&&st[a.r]==st[b.r]&&a.T<b.T) )return true;
                
    return false;
}


int a[11000],col[1100000];
int as[11000],ans;
void update(int i,int k)
{
    col[i]+=k;
    if(k==1&&col[i]==1)ans++;
    if(k==-1&&col[i]==0)ans--;
}
void solve()
{
    int l=1,r=0,T=0;
    for(int i=1;i<=qlen;i++)
    {
        while(T>q[i].T)
        {
            if(l<=c[T].x&&c[T].x<=r)
                update(c[T].be,1), update(a[c[T].x],-1);
            a[c[T].x]=c[T].be;
            T--;
        }
        while(T<q[i].T)
        {
            T++;
            if(l<=c[T].x&&c[T].x<=r)
                update(c[T].af,1), update(a[c[T].x],-1);
            a[c[T].x]=c[T].af;
        }
        
        while(l>q[i].l)l--, update(a[l],1);
        while(r<q[i].r)r++, update(a[r],1);
        while(l<q[i].l)update(a[l],-1), l++;
        while(r>q[i].r)update(a[r],-1), r--;
        
        as[q[i].id]=ans;
    }
}
char ss[5];
int main()
{
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        last[i]=a[i];
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s%d%d",ss+1,&x,&y);
        if(ss[1]==Q)
        {
            qlen++;
            q[qlen].l=x;q[qlen].r=y;
            q[qlen].T=clen;q[qlen].id=qlen;
        }    
        if(ss[1]==R)
        {
            clen++;
            c[clen].x=x;c[clen].af=y;
            c[clen].be=last[x],last[x]=y;
        }    
    }
    
    int fk=int(pow(n,0.666666));
    for(int i=1;i<=n;i++)st[i]=(i-1)/fk+1;
    sort(q+1,q+qlen+1,cmp);
    
    solve();
    
    for(int i=1;i<=qlen;i++)printf("%d\n",as[i]);
    return 0;
}

 

以上是关于bzoj2120: 数颜色的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ 2120]数颜色(带修改莫队)

[BZOJ2120][BZOJ2453]数颜色

BZOJ2453维护队列&&BZOJ2120数颜色

BZOJ 2120: 数颜色

bzoj2120: 数颜色

bzoj 2120 数颜色