ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P1903 数颜色 / 维护队列(带修莫队)

2021-09-24 02:06:08  阅读:180  来源: 互联网

标签:画笔 队列 ++ P1903 define int -- include 修莫队


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

思路:
带修莫队,与普通莫队不同的是,带修莫队在保存的询问信息中增加了一维时间,按左端点为第一关键字,右端点为第二关键字,时间为第三关键字进行排序,块的大小一般取\(n^{\dfrac{2}{3}}\)。
注意:此题中,如果用 \(getchar()\)函数进行字符输入输出,会RE最后三个点(没想明白),直接用字符串输入就不会出问题。

code:

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long 

const double eps = 1e-15;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod =  998244353;
const int maxn = 1e6 + 10;

using namespace std;

int tot, cnt, block;
int n, m, ret;
int ans[maxn], s[maxn], vis[maxn];

struct node1{
    int l, r, t, id;
    bool operator<(const node1 &a)const{
        if(a.l/block == l/block){
            if(a.r/block == r/block)return t < a.t;
            if((l/block) & 1)return r < a.r;
            else return r > a.r;
        }
        return l < a.l;
    }
}q[maxn];
struct node2{
    int x, y;
}p[maxn];

void add(int x){
    if(!vis[s[x]])ret ++;
    vis[s[x]] ++;
}

void del(int x){
    vis[s[x]] --;
    if(!vis[s[x]])ret --;
}

void work(int x, int l, int r){
    int &a = p[x].y, b = p[x].x;
    if(l <= b && b <= r){
        if(!(vis[a] ++))ret ++;
        if(!(-- vis[s[b]]))ret --;
    }   
    swap(a, s[b]);
}

int main(){
    char ch; int a, b;
    scanf("%d%d", &n, &m);
    block = pow(n, 2.0/3); 
    for(int i = 1; i <= n; i ++)scanf("%d", &s[i]);
    for(int i = 1; i <= m; i ++){
        char ch[5];
        scanf("%s", ch);
        scanf("%d%d", &a, &b);
        if(ch[0] == 'Q')q[++ tot] = {a, b, cnt, tot};
        else p[++ cnt] = {a, b};
    }
    sort(q + 1, q + tot + 1);
    int l = 0, r = 0, t = 0;
    for(int i = 1; i <= tot; i ++){
        while(l < q[i].l)del(l ++);
        while(l > q[i].l)add(-- l);

        while(r > q[i].r)del(r --);
        while(r < q[i].r)add(++ r);
        
        while(t > q[i].t)work(t --, l, r);
        while(t < q[i].t)work(++ t, l, r);
        ans[q[i].id] = ret;
    }
    for(int i = 1; i <= tot; i ++)printf("%d\n", ans[i]);
    return 0;
}

标签:画笔,队列,++,P1903,define,int,--,include,修莫队
来源: https://www.cnblogs.com/lniiwuw/p/15328252.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有