HDU 4027 Can you answer these queries?(线段树 区间不等更新)

https://vjudge.net/problem/HDU-4027#author=SUDA2019

题意 输入n个数 然后有两种操作 输入0时将给定区间所有数都变为自己的开方 输入1输出给定区间所有数的和

虽然是区间更新 但每个点更新的不一样 因此只能对单点进行更新 其实一个点最多被更新7次 \(2^{64}\) 开平方7次后就变为1了 如果某个区间的数都变为了1 那么对这个区间的开方就不用考虑了 另外要注意给你的区间可能是反的

#include
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("");
    }
}

你可能感兴趣的:(HDU 4027 Can you answer these queries?(线段树 区间不等更新))