首页 > 其他分享 >Luogu P1903 [国家集训队] 数颜色 / 维护队列

Luogu P1903 [国家集训队] 数颜色 / 维护队列

时间:2023-05-25 12:12:00浏览次数:60  
标签:ch 画笔 int Luogu P1903 add num ask 国家集训队

题目来源https://www.luogu.com.cn/problem/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

样例输入 #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 10000\)

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

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

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

本题可能轻微卡常数

来源:bzoj2120

本题数据为洛谷自造数据,使用 CYaRon 耗时5分钟完成数据制作。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

int n, m, block, l = 1, r = 0, ans;
int a[52113140], cnt[52113140], out[5211314], pos[5211314];
int ask_num, add_num;
string str;

struct ASK {
	int lift, right, time, identity;
}ask[5211314]; 

struct ADD {
	int pos, num;
}add[5211314];

inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch - '0');
		ch = getchar();
	}
	return x * f;
}

inline bool cmp_pretreat(const ASK &a, const ASK &b) {
	if (pos[a.lift] != pos[b.lift]) return pos[a.lift] < pos[b.lift];
	if (pos[a.right] != pos[b.right]) return pos[a.right] < pos[b.right];
	return a.time < b.time;
} 

inline void Del(int position) {
	if (-- cnt[a[position]] == 0) ans --;
	return;
}

inline void Add(int position) {
	if (cnt[a[position]] ++ == 0) ans ++;
	return;
}

inline void Time(int update) {
	if (add[update].pos < l || add[update].pos > r) {
		swap(add[update].num, a[add[update].pos]);
	}
	else {
		Del(add[update].pos);
		swap(add[update].num, a[add[update].pos]);
		Add(add[update].pos);
	}
	return;
}

int main() {
	ask[0].time = 0;
	cin >> n >> m; 
	block = pow(n, 1.00*2/3);
	for (int i = 1; i <= n; ++ i) {
		a[i] = read();
		pos[i] = (i - 1) / block + 1;
	}
	for (int i = 1; i <= m; ++ i) {
		cin >> str;
		if (str == "Q") {
			ask_num ++;
			ask[ask_num].lift = read();
			ask[ask_num].right = read();
			ask[ask_num].time = add_num;
			ask[ask_num].identity = ask_num;
		}
		else {
			add_num ++;
			add[add_num].pos = read();
			add[add_num].num = read(); 
		}
	}
	stable_sort(ask + 1, ask + 1 + ask_num, cmp_pretreat); 
	for (int i = 1, t = 0; i <= ask_num; ++ i) {
		while (l < ask[i].lift)  Del(l ++);
		while (l > ask[i].lift)  Add(-- l);
		while (r < ask[i].right)  Add(++ r);
		while (r > ask[i].right)  Del(r --);
		while (ask[i].time > t) Time(++ t);
		while (ask[i].time < t) Time(t --);
		out[ask[i].identity] = ans;
	}
	for (int i = 1; i <= ask_num; ++ i) {
		printf("%d\n",out[i]);
	}
	return 0;
} 

标签:ch,画笔,int,Luogu,P1903,add,num,ask,国家集训队
From: https://www.cnblogs.com/jueqingfeng/p/17430777.html

相关文章

  • 刷题笔记:Luogu P3956 棋盘
    ProblemSolutionDFS/BFS需要注意去重的时候可以重复走(因为有限定条件),只要新的步数比原来的步数小就可以走,其余情况模拟即可细节有点多,比如需要记录一下上一步的棋盘颜色(下一次搜索传递参数),因为牵扯到使用魔法问题,不能直接染,因为改变地图后后边很多操作都会受影响在列举可能性......
  • Luogu P2801 教主的魔法(Loj 数列分块入门 2)
    教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是\(N\)个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为\(1,2,\ldots,N\)。每个人的身高一开始都是不超过\(1000\)的正整数。教主的魔法每次可以把闭......
  • Luogu P5643 [PKUWC2018]随机游走
    题意给出一棵\(n\)结点树,从结点\(x\)出发,每次从当前点的所有边中选一条走过去,\(Q\)次询问给定一个点集\(S\),随机游走直到经过\(S\)中的每一个点至少一次的期望总步数,出发点\(x\)默认在开始时已经被经过。\(n\le18,Q\le5000\)解法萌新第一次见到这种题,感觉很神。......
  • Luogu P3978 [TJOI2015] 概率论
    定义\(f_i\)为\(i\)个节点组成的二叉树数量,\(g_i\)为\(i\)个节点组成的二叉树的叶子节点个数之和设当前\(i\)个节点组成的二叉树有\(a\)个叶子,容易发现分别删掉其中的\(1\)个叶子节点就能得到一个对应的\(i-1\)个节点的二叉树,总共会有\(a\)颗,可以发现每一个叶......
  • Luogu P5664 [CSP-S2019] Emiya 家今天的饭
    发现“每种主要食材至多在\(\lfloor\frac{k}{2}\rfloor\)个菜中被使用”有一个性质,在不合法的情况下绝对只有\(1\)个主要食材的个数\(>\lfloor\frac{k}{2}\rfloor\),因为\(k-\lfloor\frac{k}{2}\rfloor-1\le\lfloor\frac{k}{2}\rfloor\)然后就能发现算不合法......
  • 刷题笔记:Luogu P3743
    题目传送门Solution最多能将这些设备一起使用多久,显然答案满足单调性(如果\(x<y\)而不能使用\(x\)时间则一定不能使用\(y\)时间)通俗一点,就是前边的时间不满足则后边一定不满足,也就是局部答案舍弃性,考虑二分时间至于check怎么写呢?和奶牛晒衣服有异曲同工之妙,若设二分出来的时间......
  • 刷题笔记:Luogu P1083 借教室
    题目传送门让结果最接近\(s\)值,显然我们要二分\(w\),check的写法可以直接暴力模拟,如果check(mid)<s则将r右移(通过读公式可以知道\(w\)越小检验值\(y\)就越大)但是这样会TLE,再读一下柿子:\(y_i=\sum\limits_{j=l_i}^{r_i}[w_j\geW]\times\sum\limits_{j=l_i}^{r_i}[w_j\geW]......
  • luogu P8340 [AHOI2022] 山河重整
    题面传送门牛逼题。solution首先来推一推性质。假设我们现在有一个合法的集合,覆盖了\([1,S]\),显然新加进去的数\(i\)不能\(\geqS+2\),而如果\(\leqS+1\)那么\([1,i+S]\)显然可以被覆盖到。因此有一个\(O(n^2)\)的dp:设选到了第\(i\)个数,总和为\(j\),要求\(j\geq......
  • Luogu P5520 [yLOI2019] 青原樱
    考虑先不种花,先算出“花之间空位的可行方案数”\(tot\),乘上花的排列的贡献就能算出答案,即\(tot\timesm!\)为答案所以只需算出“花之间空位的可行方案数”能发现,设\(x_i\)为第\(i\)朵花与第\(i-1\)朵花之间空位的数量,其中设第\(0\)朵花在\(0\)的位置,则发现会有以......
  • luogu P4690 [Ynoi2016] 镜中的昆虫 题解
    P4690[Ynoi2016]镜中的昆虫题解题意维护一个长为 \(n\) 的序列 \(a_i\),有 \(m\) 次操作。将区间 \([l,r]\) 的值修改为 \(x\)。询问区间 \([l,r]\) 出现了多少种不同的数,也就是说同一个数出现多次只算一个。题解感觉这道题还是比较有意思的,像是一堆套路......