• bzoj2120 数颜色


    Description

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

    Input

    第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    Output

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

    Sample Input

    6 5
    1 2 3 4 5 5
    Q 1 4
    Q 2 6
    R 1 2
    Q 1 4
    Q 2 6

    Sample Output

    4
    4
    3
    4

    HINT

    对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

    正解:带修改莫队(分块好像也可以来着。。)

    以前一直以为莫队不能带修改,但当修改次数较少的时候,莫队其实也是一个不错的选择。。

    只要记录每次询问之前需要的修改,没修改的就修改,不该修改的就撤回,这样就能够做出这题了。。排序时先按左端点所在块排序,再按右端点所在块排序,最后按需要修改的次数排序。具体操作看代码吧。。


    //It is made by wfj_2048~
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #define inf 1<<30
    #define il inline
    #define RG register
    #define ll long long
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    
    using namespace std;
    
    struct node1{ int x,y,last; }r[10010];
    
    struct node2{ int l,r,id,tim,bl,br; }q[10010];
    
    int a[1000010],c[1000010],ans[1000010],last[1000010],n,m,L,R,cnt1,cnt2,Ans,head,block;
    char ch[3];
    
    il int gi(){
        RG int x=0,q=0; RG char ch=getchar();
        while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar();
        while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x;
    }
    
    il int cmp(const node2 &a,const node2 &b){
        if (a.bl==b.bl && a.br==b.br) return a.tim<b.tim;
        if (a.bl==b.bl) return a.br<b.br; return a.bl<b.bl;
    }
    
    il void change(RG int x,RG int y){
        if (L<=x && x<=R){
    	c[a[x]]--; if (c[a[x]]==0) Ans--; a[x]=y;
    	c[a[x]]++; if (c[a[x]]==1) Ans++;
        }else a[x]=y;
        return;
    }
    
    il void work(){
        n=gi(),m=gi(); block=sqrt(n);
        for (RG int i=1;i<=n;++i) last[i]=a[i]=gi();
        for (RG int i=1;i<=m;++i){
    	scanf("%s",ch);
    	if (ch[0]=='R'){ RG int x=gi(),col=gi(); r[++cnt1].x=x,r[cnt1].y=col,r[cnt1].last=last[x],last[x]=col; }
    	else{
    	    RG int l=gi(),r=gi(); q[++cnt2].l=l,q[cnt2].r=r,q[cnt2].id=cnt2;
    	    q[cnt2].tim=cnt1,q[cnt2].bl=(l-1)/block+1,q[cnt2].br=(r-1)/block+1;
    	}
        }
        sort(q+1,q+cnt2+1,cmp); L=1,R=0,head=0,Ans=0;
        for (RG int i=1;i<=cnt2;++i){
    	while (head<q[i].tim) head++,change(r[head].x,r[head].y);
    	while (head>q[i].tim) change(r[head].x,r[head].last),head--;
    	while (L>q[i].l){ L--,c[a[L]]++; if (c[a[L]]==1) Ans++; }
    	while (R<q[i].r){ R++,c[a[R]]++; if (c[a[R]]==1) Ans++; }
    	while (L<q[i].l){ c[a[L]]--; if (c[a[L]]==0) Ans--; L++; }
    	while (R>q[i].r){ c[a[R]]--; if (c[a[R]]==0) Ans--; R--; }
    	ans[q[i].id]=Ans;
        }
        for (RG int i=1;i<=cnt2;++i) printf("%d
    ",ans[i]); return;
    }
    
    int main(){
        File("color");
        work();
        return 0;
    }
    


  • 相关阅读:
    AtCoder Regular Contest 066 F Contest with Drinks Hard
    AtCoder Grand Contest 002 D
    AtCoder Regular Contest 076 F
    AtCoder Grand Contest 004 C
    AtCoder Regular Contest 067 F
    转载:Unity3D游戏对象消失enabled、Destroy与active的区别
    Unity3d-AngryBots实例解读
    本类对象的引用作为参数,可以直接访问其私有成员
    构建完全二叉树、控制台打印二叉树
    转载:C++类内存分布
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6416609.html
Copyright © 2020-2023  润新知