题目描述
墨墨购买了一套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 <bits/stdc++.h> using namespace std; const int maxn = 200000 + 10; int n,m,now,block,cnt[maxn],a[maxn],ans[maxn]; struct Query { int l,r,num; inline bool operator < (Query cmp) const { if (l/block != cmp.l/block) return l/block < cmp.l/block; return r < cmp.r; } }q[maxn]; inline void add(int x) { if (x > n+1) return; cnt[x]++; if (now == x && cnt[x] > 0) for (int i = x;i <= n+1;i++) if (!cnt[i]) { now = i; break; } } inline void del(int x) { if (x > n+1) return; cnt[x]--; if (!cnt[x]) now = min(now,x); } int main() { scanf("%d%d",&n,&m); block = sqrt(n); a[0] = n+2; for (int i = 1;i <= n;i++) scanf("%d",&a[i]); for (int i = 1;i <= m;i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].num = i; } sort(q+1,q+m+1); int l = 0,r = 0; for (int i = 1;i <= m;i++) { while (l < q[i].l) del(a[l++]); while (l > q[i].l) add(a[--l]); while (r < q[i].r) add(a[++r]); while (r > q[i].r) del(a[r--]); ans[q[i].num] = now; } for (int i = 1;i <= m;i++) printf("%d\n",ans[i]); return 0; }
原文地址:https://www.cnblogs.com/lrj124/p/8641642.html
时间: 2024-11-09 06:19:58