P4145 学习笔记

省流:一眼数据结构

题目传送门

肯定是使用树状数组 \(or\) 线段树进行维护的,不过这里蒟蒻认为这个毒瘤操作 \(1\) 对线段树好像不是很友好。

于是我们选择使用树状数组进行维护。

这里可以用一个 set 存所有需要开方的 \(>1\) 的数,跑的时候这样跑:

for (set <int> :: iterator i = s.lower_bound(l); i != s.upper_bound(r);) {
	int p = *i;
	update(p, -a[p]);
	a[p] = (int)sqrt(a[p]);
	update(p, a[p]);
	if (a[p] <= 1)
		i = s.erase(i);
	else 
		i++;
}

其余正常维护即可。

code
/**********************************************************
 * Author        : dingziyang888
 * Website       : https://www.luogu.com.cn/problem/
 * Created Time  :
 * FileName      :
 * Warning!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * 1.MLE?
 * 2.array size enough?
 * 3.long long?
 * 4.overflow long long?
 * 5.multiple task cleaned?
 * 6.freopen?
 * 7.TLE?
 * *******************************************************/
#include <iostream>
#include <set>
#include <cmath>
#define DEBUG
#define Ofile(s) freopen(s".in", "r", stdin), freopen (s".out", "w", stdout)
#define Cfile(s) fclose(stdin), fclose(stdout)
#define fast ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define int long long
using namespace std;

using ll = long long;
using ull = unsigned long long;
using lb = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;

constexpr int mod = 998244353;
constexpr int maxn = 100005;

int n, q, opt, l, r;

int a[maxn], c[maxn];

set <int> s;

int lowbit(int x) {
	return x & (-x);
}

int query(int x) {
	int res = 0;
	for (int i = x; i > 0; i -= lowbit(i))
		res += c[i];
	return res;
}

void update(int x, int y) {
	for (int i = x; i <= n; i += lowbit(i))
		c[i] += y;
}

signed main() {
	fast;
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	for (int i = 1; i <= n; i++)
		update(i, a[i]);
	for (int i = 1; i <= n; i++)
		if (a[i] > 1)
			s.insert(i);
	cin >> q;
	while (q--) {
		cin >> opt >> l >> r;
		if (l > r)
			swap(l, r);
		if (opt)
			cout << query(r) - query(l - 1) << endl;
		else 
			for (set <int> :: iterator i = s.lower_bound(l); i != s.upper_bound(r);) {
				int p = *i;
				update(p, -a[p]);
				a[p] = (int)sqrt(a[p]);
				update(p, a[p]);
				if (a[p] <= 1)
					i = s.erase(i);
				else 
					i++;
			}

	}
	return 0;
}
posted @ 2026-02-10 10:28  constexpr_ll  阅读(4)  评论(0)    收藏  举报