【P4145】 上帝造题的七分钟2 / 花神游历各国

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;
}

 

转载于:https://www.cnblogs.com/-sheldon/p/11488162.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值