You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//#include <bits/stdc++.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <math.h>
#include <cstdio>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
LL a[N];
struct Node {
int l, r;
LL sum; //区间和
} tr[N << 2];
void pushup(int u) {
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u, int l, int r) {
tr[u] = {l, r};
if (l == r) {
tr[u].sum = a[l]; //构建线段树,叶子节点给定初始值
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
//更新父节点信息
pushup(u);
}
void modify(int u, int l, int r) {
//减枝 如果区间和等于区间长度说明每个节点值都是1此时再开方没有意义
if (tr[u].sum == (tr[u].r - tr[u].l + 1)) return;
//如果在区间内
if (tr[u].l == tr[u].r) {
tr[u].sum = (LL)sqrt(tr[u].sum); //暴力开方
return;
}
//中点
int mid = (tr[u].l + tr[u].r) >> 1;
//与左儿子有交集,递归修改左儿子
if (l <= mid) modify(u << 1, l, r);
//与右儿子有交集,递归修改右儿子
if (r > mid) modify(u << 1 | 1, l, r);
//向父节点传递统计信息
pushup(u);
}
//非常标准的查询
LL query(int u, int l, int r) {
if (r < tr[u].l || l > tr[u].r) return 0;
if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
return query(u << 1, l, r) + query(u << 1 | 1, l, r);
}
int main() {
int n, q, cas = 1;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
build(1, 1, n);
scanf("%d", &q);
while (q--) {
int c, l, r;
scanf("%d%d%d", &c, &l, &r);
if (l > r) swap(l, r); /// l可能大于r
if (c == 0)
modify(1, l, r);
else
printf("%lld\n", query(1, l, r));
}
printf("\n");
return 0;
}