Description

Input

Output

每次x=1时,每行一个整数,表示这次旅行的开心度

Sample Input
4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

Sample Output
101

11

11

HINT

对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9

线段树经典套路了。偶然碰到了,再写一次

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
#define lson l,m,o*2
#define rson m+1,r,o*2+1
namespace segmenttree{
    int c[maxn*4];
    long long sum[maxn*4];
    void pushup(int o){
        sum[o] = sum[o*2] + sum[o*2+1];
        c[o] = c[o*2] || c[o*2+1] ? 1: 0;
    }
    void build(int l, int r, int o){
        if(l == r){
            scanf("%lld", &sum[o]);
            c[o] = sum[o] > 1 ? 1: 0;
            return;
        }
        int m = (l + r) / 2;
        build(lson);
        build(rson);
        pushup(o);
    }
    void update(int L, int R, int l, int r, int o){
        if(!c[o]) return;
        if(l == r){
            sum[o] = sqrt(sum[o]);
            if(sum[o] <= 1) c[o] = 0;
            return;
        }
        int m = (l + r) / 2;
        if(L <= m && c[o*2]) update(L, R, lson);
        if(m < R && c[o*2+1]) update(L, R, rson);
        pushup(o);
    }
    long long query(int L, int R, int l, int r, int o){
        if(L <= l && r <= R) return sum[o];
        int m = (l + r) / 2;
        if(R <= m) return query(L, R, lson);
        else if(L > m) return query(L, R, rson);
        else{
            return query(L, m, lson) + query(m + 1, R, rson);
        }
    }
}
using namespace segmenttree;

int main(){
    int n, m;
    scanf("%d", &n);
    build(1, n, 1);
    scanf("%d", &m);
    for(int i = 1; i <= m; i++){
        int cmd, l, r;
        scanf("%d%d%d", &cmd, &l, &r);
        if(cmd == 1) printf("%lld\n", query(l, r, 1, n, 1));
        else update(l, r, 1, n, 1);
    }
    return 0;
}