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;
}

浙公网安备 33010602011771号