hdu 4027(区间更新)

来源:互联网 发布:中国软件资讯网 编辑:程序博客网 时间:2024/05/02 01:30

题意:有n个数字,q次询问,两种操作0 x y 把区间[x,y]全部开根号,1 x y 询问区间[x,y]数字和。
题解:q的范围到100000,题目中说数字最大2^63,所以一个数字最多开7次根就是1不再变化了,所以用一个线段树维护每个数字还能开多少次根号,区间维护最大值,如果某个区间的最大次数已经是0,就不用更新了。一直wa,然后发现有可能x > y,吐血。。。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define ll long longusing namespace std;const int N = 100005;int n, q, num[N << 2], b[N];ll arr[N], tree[N << 2], flag[N << 2];void pushup(int k) {    tree[k] = tree[k * 2] + tree[k * 2 + 1];    num[k] = max(num[k * 2], num[k * 2 + 1]);}void build(int k, int left, int right) {    if (left == right) {        tree[k] = arr[left];        num[k] = b[left];        return;    }    int mid = (left + right) / 2;    build(k * 2, left, mid);    build(k * 2 + 1, mid + 1, right);    pushup(k);}void modify(int k, int left, int right, int l, int r) {    if (l <= left && right <= r) {        if (num[k] == 0) {            return;        }        if (left == right) {            tree[k] = sqrt(tree[k]);            num[k]--;        }        else {            int mid = (left + right) / 2;            if (l <= mid)                modify(k * 2, left, mid, l, r);            if (r > mid)                modify(k * 2 + 1, mid + 1, right, l, r);            pushup(k);        }        return;    }    int mid = (left + right) / 2;    if (l <= mid)        modify(k * 2, left, mid, l, r);    if (r > mid)        modify(k * 2 + 1, mid + 1, right, l, r);    pushup(k);}ll query(int k, int left, int right, int l, int r) {    if (l <= left && right <= r)        return tree[k];    int mid = (left + right) / 2;    ll res = 0;    if (l <= mid)        res += query(k * 2, left, mid, l, r);           if (r > mid)        res += query(k * 2 + 1, mid + 1, right, l, r);    pushup(k);    return res;}int main() {    int cas = 1;    while (scanf("%d", &n) == 1) {        for (int i = 1; i <= n; i++) {            scanf("%lld", &arr[i]);            ll temp = arr[i];            int cnt = 0;            while (temp != 1) {                cnt++;                temp = sqrt(temp);            }            b[i] = cnt;        }        build(1, 1, n);        scanf("%d", &q);        int op, l, r;        printf("Case #%d:\n", cas++);        while (q--) {            scanf("%d%d%d", &op, &l, &r);            if (l > r) swap(l, r);            if (op == 0)                modify(1, 1, n, l, r);            else {                printf("%lld\n", query(1, 1, n, l, r));            }        }        printf("\n");    }    return 0;}
0 0