zoukankan      html  css  js  c++  java
  • [国家集训队]数颜色 / 维护队列(带修莫队)

    题目描述

    墨墨购买了一套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
    ",&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
    ",x[i].ans);
        }
    }
  • 相关阅读:
    喜欢的诗
    诗集与集诗
    oracle 12c 中asm元数据是否有所变化
    hdu2066一个人的旅行(dijkstra)
    单链表
    ExtJS4.2学习(7)——基础知识之Reader&Writer篇
    hdu3790最短路径问题 (用优先队列实现的)
    poj 1220 NUMBER BASE CONVERSION(短除法进制转换)
    POJ 4003 Bob’s Race && HDU4123 Bob’s Race (dfs+rmq)
    全排列
  • 原文地址:https://www.cnblogs.com/ztz11/p/9807459.html
Copyright © 2011-2022 走看看