Live2D

[国家集训队]数颜色 / 维护队列(带修莫队)

题目描述

墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:

1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。

2、 R P Col 把第P支画笔替换为颜色Col。

为了满足墨墨的要求,你知道你需要干什么了吗?

输入输出格式

输入格式:

第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。

第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。

第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

输出格式:

对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

思路:

带修莫队裸题

和正常莫队相比,多了一维时间

我们可以把时间当作修改

在莫队的排序时作为第三关键字

在左右端点都处理好后,看时间戳

如果需要修改就修改

当然,我们要提前与处理操作

添加反向操作

便于回滚

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define rii register int i
#define rij register int j
using namespace std;
struct que{
    int l,r,t,ans;
}x[50005];
struct change{
    int wz,color,t;
}y[50005][2];
int a[50005],n,m,sum[1000005],nl,nr,nt,ans,cnt,sy[50005],bnt;
bool cmp1(que lk,que kl)
{
    if(sy[lk.l]==sy[kl.l])
    {
        if(sy[lk.r]==sy[kl.r])
        {
            return lk.t<kl.t;
        }
        return sy[lk.r]<sy[kl.r];
    }
    return sy[lk.l]<sy[kl.l];
}
bool cmp2(que lk,que kl)
{
    return lk.t<kl.t;
}
void ycl()
{
    int b[50005];
    for(rii=1;i<=n;i++)
    {
        b[i]=a[i];
    }
    for(rii=1;i<=bnt;i++)
    {
        y[i][1].wz=y[i][0].wz;
        y[i][1].color=b[y[i][0].wz];
        y[i][1].t=y[i][0].t-1;
        b[y[i][0].wz]=y[i][0].color;
    }
}
void change(int wz,int val)
{
    sum[a[wz]]+=val;
    if(val==1&&sum[a[wz]]==1)
    {
        ans++;
    }
    if(val==-1&&sum[a[wz]]==0)
    {
        ans--;
    }
}
int main()
{
//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);
    scanf("%d%d",&n,&m);
    int len=pow(n,(2.0/3));
    for(rii=1;i<=n;i++)
    {
        scanf("%d ",&a[i]);
        sy[i]=i/len+1;
    }    
    for(rii=1;i<=m;i++)
    {
        char c;
        int ltt,kkk;
        scanf("%c%d%d\n",&c,&ltt,&kkk);
        if(c=='Q')
        {
            cnt++;
            x[cnt].l=ltt,x[cnt].r=kkk;
            x[cnt].t=i;
        }
        else
        {
            bnt++;
            y[bnt][0].wz=ltt;
            y[bnt][0].color=kkk;
            y[bnt][0].t=i;
        }
    }
    y[bnt+1][0].t=2147483647;
    y[bnt-1][1].t=-1;
    ycl();
    sort(x+1,x+cnt+1,cmp1);
    nl=1,nr=1,ans=1,sum[a[1]]=1;
    int bh=0;
    for(rii=1;i<=cnt;i++)
    {
        while(nl<x[i].l)
        {
            change(nl,-1);
            nl++;
        }
        while(nl>x[i].l)
        {
            change(nl-1,1);
            nl--;
        }
        while(nr<x[i].r)
        {
            change(nr+1,1);
            nr++;
        }
        while(nr>x[i].r)
        {
            change(nr,-1);
            nr--;
        }
        int pd=0;
        while(nt<x[i].t)
        {
            if(pd==0)
            {
                pd++;
                bh--;
                if(y[bh+1][0].t<nt)
                {
                    bh++;
                }
            }
            if(y[bh+1][0].t>x[i].t)
            {
                break;
            }
            bh++;
            if(y[bh][0].wz>=nl&&y[bh][0].wz<=nr)
            {
                sum[a[y[bh][0].wz]]--;
                if(sum[a[y[bh][0].wz]]==0)
                {
                    ans--;
                }
                sum[y[bh][0].color]++;
                if(sum[y[bh][0].color]==1)
                {
                    ans++;
                }
            }
            a[y[bh][0].wz]=y[bh][0].color;
            nt=y[bh][0].t;
        }
        pd=0;
        while(nt>=x[i].t)
        {
            if(pd==0)
            {
                pd=1;
                bh++;
                if(y[bh-1][1].t>=nt)
                {
                    bh--;
                }
            }
            if(y[bh-1][1].t<x[i].t)
            {
                break;
            }
            bh--;
            if(y[bh][1].wz>=nl&&y[bh][1].wz<=nr)
            {
                sum[a[y[bh][1].wz]]--;
                sum[y[bh][1].color]++;
                if(sum[a[y[bh][1].wz]]==0)
                {
                    ans--;
                }
                if(sum[y[bh][1].color]==1)
                {
                    ans++;
                }
            }
            a[y[bh][1].wz]=y[bh][1].color;
            nt=y[bh][1].t;
        }
        x[i].ans=ans;
    }
    sort(x+1,x+cnt+1,cmp2);
    for(rii=1;i<=cnt;i++)
    {
        printf("%d\n",x[i].ans);
    }
}

 

posted @ 2018-10-17 22:00  ztz11  阅读(269)  评论(0编辑  收藏  举报