Codrforces-Range Update Point Query

题目

前言

给一个不是线段树的朴素写法。

这道题很久以前就想写题解的,不过忘了,于是今天补下。

思路

考虑一个数大于 \(9\) 的时候,很明显是可以进行操作的,于是我们要把它放进集合里,然后一个数不能再操作的时候我们要删掉它,这边注意了,直接删除的时间复杂度是\(\mathcal{O(n)。}\)

但是我们可以把要删的用迭代器存入专门的容器就行了\(\mathcal{O(1)。}\)
但是记住千万别边循环边删,这样会改变整个容器结构,导致迭代器失效!然后没用的直接删除,这样整个代码均摊下来时间肯定是可以的!

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int q;
int a[200005];
int  check(int num) {
	int sum = 0;
	while (num) {
		sum += num % 10;
		num /= 10;
	}
	return sum;
}
void solve() {
	cin >> n;
	cin >> q;
	int op;
	int l, r;
	set<int>s;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (a[i] > 9)s.insert(i);
	}
	for (int i = 1; i <= q; i++) {
		cin >> op;
		if (op == 1) {
			cin >> l >> r;
			set<int>::iterator it;
			vector<set<int>::iterator>todel;
			for (it = s.lower_bound(l); it != s.end() && *it <= r; it++) {
				a[*it] = check(a[*it]);
				if (a[*it] < 10) {
					todel.push_back(it);
				}
			}
			for (auto x : todel) {
				s.erase(x);
			}
		} else {
			cin >> l;
			cout << a[l] << endl;
		}
	}
	return ;
}
signed main() {
	int t;
	ios::sync_with_stdio();
	cin.tie(0);
	cout.tie(0);
	cin >> t;
	for (int i = 1; i <= t; i++)solve();
	return 0;


}
posted @ 2025-04-16 19:47  LteShuai  阅读(21)  评论(0)    收藏  举报