Spoj 2713 Can you answer these queries IV 水线段树

题目链接:点击打开链接

题意:

给定n长的序列

以下2个操作

0 x y 给[x,y]区间每一个数都 sqrt

1 x y 问[x, y] 区间和

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define N 100005
#define L(x) tree[x].l
#define R(x) tree[x].r
#define Lson(x) (x<<1)
#define Rson(x) (x<<1|1)
#define Num(x) tree[x].num
#define Sum(x) tree[x].sum
inline int Mid(int x, int y){return (x+y)>>1;}
struct Subtree{
    int l, r;
    ll num, sum;
}tree[N<<2];
ll a[N];
void push_up(int id){
    if(L(id) == R(id))return;
    Sum(id) = Sum(Lson(id)) + Sum(Rson(id));
    if(Num(Lson(id)) <= 1  && Num(Rson(id)) <= 1)
        Num(id) = 1;
    else Num(id) = 2;
}
void build(int l, int r, int id){
    L(id) = l; R(id) = r;
    if(l == r) { Num(id) = Sum(id) = a[l]; return ;}
    int mid = Mid(l, r);
    build(l, mid, Lson(id));
    build(mid+1, r, Rson(id));
    push_up(id);
}
void updata(int l, int r, int id){
    if(L(id) == R(id))
    {
        Sum(id) = Num(id) = (ll)sqrt((double)Sum(id));
        return ;
    }
    if(l == L(id) && R(id) == r && Num(id) <= 1) return ;

    int mid = Mid(L(id), R(id));
    if(mid < l)
        updata(l, r, Rson(id));
    else if(r <= mid)
        updata(l, r, Lson(id));
    else {
        updata(l, mid, Lson(id));
        updata(mid+1, r, Rson(id));
    }
    push_up(id);
}
ll query(int l, int r, int id){
    if(l == L(id) && R(id) == r)
        return Sum(id);
    int mid = Mid(L(id), R(id));
    if(mid < l)
        return query(l, r, Rson(id));
    else if(r <= mid)
        return query(l, r, Lson(id));
    else return query(l, mid, Lson(id)) + query(mid+1, r, Rson(id));
}
int n;
void solve(){
    int q, op, x, y;
    for(int i = 1; i <= n; i++)scanf("%lld", &a[i]);
    build(1, n, 1);
    scanf("%d",&q);
    while(q--){
        scanf("%d %d %d", &op, &x, &y);
        if(x > y) swap(x, y);
        if(op == 0)
            updata(x, y, 1);
        else
            printf("%lld
", query(x, y, 1));
    }
}
int main(){
    int Cas = 1;
	while(~scanf("%d", &n)){
        printf("Case #%d:
", Cas++);
        solve();
        puts("");
	}
	return 0;
}


原文地址:https://www.cnblogs.com/mfrbuaa/p/5198479.html