https://vjudge.net/problem/HDU-4027#author=SUDA2019
题意 输入n个数 然后有两种操作 输入0时将给定区间所有数都变为自己的开方 输入1输出给定区间所有数的和
虽然是区间更新 但每个点更新的不一样 因此只能对单点进行更新 其实一个点最多被更新7次 \(2^{64}\) 开平方7次后就变为1了 如果某个区间的数都变为了1 那么对这个区间的开方就不用考虑了 另外要注意给你的区间可能是反的
#include<bits/stdc++.h>
typedef long long ll;
#define mid (l+r)/2
#define lch in*2
#define rch in*2+1
const int maxn = 1e5 + 9;
int N, M, L, R;
ll tr[maxn * 4] = {};
void build(int in = 1, int l = 1, int r = N) {
if (l == r) return void(scanf("%lld", tr + in));
build(lch, l, mid); build(rch, mid + 1, r);
tr[in] = tr[lch] + tr[rch];
}
void update(int in = 1, int l = 1, int r = N) {
if (l > R || r < L || tr[in] == (r - l + 1)) return;
if (l == r) return void(tr[in] = sqrt(tr[in]));
update(lch, l, mid); update(rch, mid + 1, r);
tr[in] = tr[lch] + tr[rch];
}
ll qurry(int in = 1, int l = 1, int r = N) {
if (l > R || r < L) return 0;
if (L <= l && R >= r) return tr[in];
return qurry(lch, l, mid) + qurry(rch, mid + 1, r);
}
void solve() {
build();
scanf("%d", &M);
while (M--) {
int t; scanf("%d%d%d", &t, &L, &R);
if (L > R) L ^= R ^= L ^= R;
if (!t) update();
else printf("%lld\n", qurry());
}
}
int main() {
//freopen("in.txt", "r", stdin);
for (int __ = 1; ~scanf("%d", &N);) {
printf("Case #%d:\n", __++);
solve();
puts("");
}
}