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