Description
给定一个序列,还有操作数m,对于每个m,你需要将一段区间开方,还有求和
Solution
线段树维护,比较简单,可以当做练习题
Code
#include <bits/stdc++.h> const long long N = 1e5 + 10; using namespace std; long long n, m; long long a[N]; struct emmm { long long l, r, sum, ma; #define l(x) tr[x].l #define r(x) tr[x].r #define sum(x) tr[x].sum #define ma(x) tr[x].ma } tr[N << 2]; void build(long long p, long long l, long long r) { l(p) = l; r(p) = r; if (l == r) { sum(p) = ma(p) = a[l]; return ; } long long mid = (l + r) >> 1; build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r); sum(p) = sum(p << 1) + sum(p << 1 | 1); ma(p) = max(ma(p << 1), ma(p << 1 | 1)); } void change(long long p, long long l, long long r) { if (ma(p) == 0 || ma(p) == 1) return ; if (l(p) == r(p) && l(p) >= l && r(p) <= r) { sum(p) = ma(p) = sqrt(sum(p)); return ; } long long mid = (l(p) + r(p)) >> 1; if (l <= mid) change(p << 1, l, r); if (r > mid) change(p << 1 | 1, l, r); sum(p) = sum(p << 1) + sum(p << 1 | 1); ma(p) = max(ma(p << 1), ma(p << 1 | 1)); } long long ask(long long p, long long l, long long r) { if (l <= l(p) && r >= r(p)) return sum(p); long long mid = (l(p) + r(p)) >> 1; long long ans = 0; if (l <= mid) ans += ask(p << 1, l, r); if (r > mid) ans += ask(p << 1 | 1, l, r); return ans; } int main() { scanf("%lld", &n); for (long long i = 1; i <= n; i++) scanf("%lld", &a[i]); build(1, 1, n); scanf("%lld", &m); while (m--) { long long k, l, r; scanf("%lld%lld%lld", &k, &l, &r); if (l > r) swap(l, r); if (k) cout << ask(1, l, r) << endl; else change(1, l, r); } return 0; }