Java教程

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

本文主要是介绍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

说明/提示

对于30%的数据,n,m \leq 10000n,m≤10000

对于60%的数据,n,m \leq 50000n,m≤50000

对于所有数据,n,m \leq 133333n,m≤133333

所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

本题可能轻微卡常数

 

因为某些nt操作导致改了一天的bug, 所以记录一下 (不仔细读题的下场

 

排序条件尽量用三元表达式, 避免使用if else if, 后者花的时间很可能是不可接受的

举个例子, 上面是三元表达式排序, 下面是if else if判断排序, 时间差距甚至达到了一倍甚至更多

 

 

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <climits>
  4 #include <cmath>
  5 using namespace std;
  6 constexpr int MAXN = 2e6 + 7, MAXM = 2e6 + 7, inf = 0x3f3f3f3f;
  7 typedef long long ll;
  8 int Block_Size, n, m;
  9 int a[MAXN], id[MAXN], color[MAXN], ans[MAXN], res, qc, mc, ls = 1, rs;
 10 
 11 inline int read()
 12 {
 13     char c = getchar();
 14     int x = 0, f = 1;
 15     while (c < '0' || c > '9')
 16     {
 17         if (c == '-')
 18             f = -1;
 19         c = getchar();
 20     }
 21     while (c >= '0' && c <= '9')
 22     {
 23         x = x * 10 + c - '0', c = getchar();
 24     }
 25     return x * f;
 26 }
 27 struct query
 28 {
 29     int l;
 30     int r;
 31     int qid;
 32     int time;
 33     query(int l = 0, int r = 0, int qid = 0, int time = 0) : l(l), r(r), qid(qid), time(time)
 34     {
 35     }
 36 
 37     bool operator<(const query &other) const
 38     {
 39         //一定要避免使用if else if的形式!!!!
 40         //例如下面的写法
 41 
 42         return id[l] == id[other.l] ? id[r] == id[other.r] ? time < other.time : r < other.r : l < other.l;
 43         // if (id[l] == id[other.l])
 44         // {
 45         //     if (id[r] == id[other.r])
 46         //         return l < other.l;
 47         //     return r < other.r;
 48         // }
 49         // return time < other.time;
 50     }
 51 } q[MAXM];
 52 
 53 struct modify
 54 {
 55     int pos;
 56     int val;
 57     modify(int pos = 0, int val = 0) : pos(pos), val(val)
 58     {
 59     }
 60 } mod[MAXM];
 61 
 62 void del(int val)
 63 {
 64     if (--color[val] == 0)
 65         --res;
 66 }
 67 
 68 void add(int val)
 69 {
 70     if (++color[val] == 1)
 71         ++res;
 72 }
 73 
 74 void update(int x, int i)
 75 {
 76     if (q[i].l <= mod[x].pos && mod[x].pos <= q[i].r)
 77     {
 78         del(a[mod[x].pos]);
 79         add(mod[x].val);
 80     }
 81     swap(a[mod[x].pos], mod[x].val);
 82 }
 83 
 84 int main()
 85 {
 86     char op;
 87     int l, r, now = 0;
 88     n = read();
 89     m = read();
 90     Block_Size = pow(n, 2.0 / 3.0);
 91     for (int i = 1; i <= n; ++i)
 92     {
 93         a[i] = read();
 94         id[i] = (i - 1) / Block_Size;
 95     }
 96 
 97     for (int i = 1; i <= m; ++i)
 98     {
 99         scanf("%c", &op);
100         l = read();
101         r = read();
102         if (op == 'R')
103         {
104             ++mc;
105             mod[mc].pos = l;
106             mod[mc].val = r;
107         }
108         else
109         {
110             ++qc;
111             q[qc].l = l;
112             q[qc].r = r;
113             q[qc].time = mc;
114             q[qc].qid = qc;
115         }
116     }
117     sort(q + 1, q + qc + 1);
118 
119     for (int i = 1; i <= qc; ++i)
120     {
121         while (ls < q[i].l)
122             del(a[ls++]);
123         while (ls > q[i].l)
124             add(a[--ls]);
125 
126         while (rs < q[i].r)
127             add(a[++rs]);
128         while (rs > q[i].r)
129             del(a[rs--]);
130 
131         while (now < q[i].time)
132             update(++now, i);
133         while (now > q[i].time)
134             update(now--, i);
135 
136         ans[q[i].qid] = res;
137     }
138 
139     for (int i = 1; i <= qc; ++i)
140     {
141         printf("%d\n", ans[i]);
142     }
143 
144     return 0;
145 }
AC code

 

 

 

 

 

 

这篇关于P1903 [国家集训队]数颜色 / 维护队列 (带修莫队)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!