题解:P11139 [APC001] D - Array Again

题面

[APC001] D - Array Again

题目描述

你需要维护一个数列,支持 \(4\) 种操作:

  1. 1 x y:连续向数列中插入 \(y\) 个数 \(x\)
  2. 2 x y:连续在数列中删除 \(y\)\(x\)。如果在某一次删除中 \(x\) 已经不存在于数列中,则忽略此操作。
  3. 3:对数列进行去重,即,对于每个在数列中出现过的不同的正整数 \(x\),如果它在数列中出现了大于 \(1\) 次,则只在数列中保留一个 \(x\),其余全部删除。
  4. 4 x:查询数列中 \(x\) 的出现次数。

对于每个操作 \(4\),请求出其答案。

输入格式

第一行一个整数 \(q\),表示询问次数。

接下来 \(q\) 行,每行若干个整数,表示一次操作。

输出格式

对于每次操作 \(4\) 输出一行,表示其答案。

数据保证至少有一次操作 \(4\)

样例 #1

样例输入 #1

5
1 2 10
2 2 5
4 2
3
4 2

样例输出 #1

5
1

样例 #2

样例输入 #2

4
1 1000000000 1000000000
1 1000000000 1000000000
1 1000000000 1000000000
4 1000000000

样例输出 #2

3000000000

样例 #3

样例输入 #3

20
4 95002957
2 384405322 255642125
2 384405322 174926753
2 384405322 51265222
1 384405322 311383201
4 384405322
1 384405322 5464229
4 22438767
4 17075617
1 384405322 153189933
1 230228188 148299369
1 7168162 387115701
1 384405322 154480360
1 384405322 438458686
3
1 7961090 98996809
4 153074129
1 975025351 171484003
1 384405322 650527951
4 384405322

样例输出 #3

0
311383201
0
0
0
650527952

提示

样例解释 \(1\)

\(1\) 次操作:插入 \(10\)\(2\)

\(2\) 次操作:删除 \(5\)\(2\)。此后数列中只包含 \(5\)\(2\)

\(3\) 次操作:查询 \(2\) 的出现次数,共 \(5\) 次。

\(4\) 次操作:对数列进行去重。此后数列中只包含一个 \(2\)

\(5\) 次操作:查询 \(2\) 的出现次数,共 \(1\) 次。

样例解释 \(2\)

请注意答案可能会超过 \(32\) 位整型的范围。

数据范围

对于 \(100\%\) 的数据,\(1\le q\le 10^5\)\(1\le x,y\le 10^9\)

题解

思路

这道题目需要统计每个数字的出现个数,为了保证不会喜提 MLE,这里使用 map 来进行维护。但是这里并不需要 map 的排序功能,所以采用时间效率更高的 unordered_map

这道题目仅仅需要将 \(4\) 种操作写出来即可。

操作一:连续向数列中插入 \(y\)\(x\)

void f1() {
	scanf("%lld %lld",&x,&y);
	v[x] += y;//直接加 y
}

操作二:连续在数列中删除 \(y\)\(x\)

void f2() {  
	scanf("%lld %lld", &x, &y);  
	auto it = v.find(x);  
	if (it != v.end()) {  //序列中存在 x 
		if (it->second <= y)	v.erase(it);  //数量不够直接删
		else	it->second -= y;
    }
}

操作三:对数列进行去重

因为在操作二中已经将不存在的数删去,所以就可以将存在的数的个数变为一。

void f3() {
	for (auto it = v.begin(); it != v.end(); it++)//从头到尾遍历一遍
		it->second = 1;
}

操作四:查询数列中 \(x\) 的出现次数

void f4() {
	scanf("%lld",&x);
	if (v.find(x) != v.end())	printf("%lld\n",v[x]);
	else	printf("%lld\n",0);
}

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
unordered_map<int, int> v;
int n, o, x, y;
void f1() {
	scanf("%lld %lld",&x,&y);
	v[x] += y;
}
void f2() {  
	scanf("%lld %lld", &x, &y);  
	auto it = v.find(x);  
	if (it != v.end()) { 
		if (it->second <= y)	v.erase(it);
		else	it->second -= y;
    }
}
void f3() {
	for (auto it = v.begin(); it != v.end(); it++)
		it->second = 1;
}
void f4() {
	scanf("%lld",&x);
	if (v.find(x) != v.end())	printf("%lld\n",v[x]);
	else	printf("%lld\n",0);
}

signed main() {
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> o;
		if (o == 1)	f1();
		if (o == 2)	f2();
		if (o == 3)	f3();
		if (o == 4)	f4();
	}
	return 0;
}
posted @ 2024-10-02 18:31  ggc114514  阅读(34)  评论(0)    收藏  举报