zoukankan      html  css  js  c++  java
  • P1903 [国家集训队]数颜色 / 维护队列 莫对算法

      

    题目描述

    墨墨购买了一套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支画笔中共有几种不同颜色的画笔。

    输入输出样例

    输入样例#1: 复制
    6 5
    1 2 3 4 5 5
    Q 1 4
    Q 2 6
    R 1 2
    Q 1 4
    Q 2 6
    输出样例#1: 复制
    4
    4
    3
    4


    为带修莫队 增加一维即可解决
    如果还按照原来的方式cmp的话T到飞起 增加的那一维也要排序!!!
    因为要来回的修改 与退回
    所以swap非常的巧妙
    #include<bits/stdc++.h>
    
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    //////////////////////////////////////
    const int N=1e6+4;
    struct node
    {
        int l,r,pre,id;
    }s[N];
    struct query
    {
        int val,pos;
    }s2[N];
    int n,m,a[N],L,R,now,ans,anss[N],cnt[N],cntq,cntr,x,y,block; 
    char ss[2];
    bool cmp(node a,node b)
    {
        return a.l/block==b.l/block?  a.r/block==b.r/block?  a.pre<b.pre:  a.r<b.r:   a.l<b.l;//三个元素玄学排序
    }
    void add(int x)
    {
        if(++cnt[a[x]]==1)ans++;
    }
    void del(int x)
    {
        if(--cnt[a[x]]==0)ans--;
    }
    void work(int now,int i)
    {
        if(s2[now].pos>=s[i].l&&s2[now].pos<=s[i].r)
        {
            if(--cnt[ a[s2[now].pos] ]==0)ans--;
            if(++cnt[ s2[now].val ]==1)ans++;
        }
        swap(s2[now].val,a[s2[now].pos]);
    }
    int main()
    {
        RII(n,m);rep(i,1,n)RI(a[i]);
    
        rep(i,1,m)
        {
            RS(ss);RII(x,y);
            if(ss[0]=='Q')
            {
                s[++cntq].l=x;s[cntq].r=y;s[cntq].pre=cntr;s[cntq].id=cntq;
            }
            else
            {
                s2[++cntr].pos=x;s2[cntr].val=y;
            }
        }
        block=sqrt(n)*15;
    
        sort(s+1,s+1+cntq,cmp);
    
        int L=1,R=0,now=0;
        rep(i,1,cntq)
        {
            int l=s[i].l,r=s[i].r;
            while(L<l)del(L++);
            while(L>l)add(--L);
            while(R<r)add(++R);
            while(R>r)del(R--);
            while(now<s[i].pre)work(++now,i);
            while(now>s[i].pre)work(now--,i);
            anss[s[i].id]=ans;
        }
        rep(i,1,cntq)cout<<anss[i]<<endl;
    
        return 0;
    }
    View Code


  • 相关阅读:
    Django框架介绍
    CSS基础
    BOM与DOM操作
    JavaScript
    PHP Socket编程 之 fsockopen链接https时OpenSSL错误
    PHP Socket编程 之 深入解析fsockopen与pfsockopen的区别
    PHP Socket编程 之 使用fsockopen伪造IP
    PHP Socket编程 之 利用 fsockopen() 函数开放端口扫描器的实例
    PHP Socket编程 之 fsockopen指定ip获取远程数据 及 301自动跳转
    PHP Socket编程 之 抓取数据遇到Transfer-Encoding chunked
  • 原文地址:https://www.cnblogs.com/bxd123/p/10922969.html
Copyright © 2011-2022 走看看