题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=3211
题目大意:
思路:
由于数据范围只有1e9,一个数字x开根号次数超过logx之后均为1,所以可以暴力开根号,但是需要剪枝优化,如果子树的max小于等于1,那么直接跳过即可。否则递归到叶子节点暴力开根号。
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
#define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Mem(a) memset(a, 0, sizeof(a))
#define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
#define MID(l, r) ((l) + ((r) - (l)) / 2)
#define lson ((o)<<1)
#define rson ((o)<<1|1)
#define Accepted 0
#pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} typedef long long ll;
const int maxn = + ;
const int MOD = ;//const引用更快,宏定义也更快
const int INF = 1e9 + ;
const double eps = 1e-; ll a[maxn];
struct node
{
int l, r;
ll mmax, sum;
}tree[maxn<<];
void build(int o, int l, int r)
{
tree[o].l = l, tree[o].r = r;
if(l == r)
{
tree[o].mmax = tree[o].sum = a[l];
return;
}
int m = MID(l, r);
build(lson, l, m);
build(rson, m + , r);
tree[o].mmax = Max(tree[lson].mmax, tree[rson].mmax);
tree[o].sum = tree[lson].sum + tree[rson].sum;
}
int ql, qr;
ll sum;
void query(int o)
{
if(ql <= tree[o].l && qr >= tree[o].r)
{
sum += tree[o].sum;
return;
}
if(ql <= tree[lson].r)query(lson);
if(qr >= tree[rson].l)query(rson);
}
void update(int o)
{
if(tree[o].mmax <= )return;
if(tree[o].l == tree[o].r)
{
tree[o].mmax = tree[o].sum = sqrt(1.0 * tree[o].mmax);
return ;
}
if(ql <= tree[lson].r)update(lson);
if(qr >= tree[rson].l)update(rson);
tree[o].mmax = Max(tree[lson].mmax, tree[rson].mmax);
tree[o].sum = tree[lson].sum + tree[rson].sum;
}
int main()
{
int n, m;
scanf("%d", &n);
for(int i = ; i <= n; i++)scanf("%d", &a[i]);
build(, , n);
scanf("%d", &m);
while(m--)
{
int op;
scanf("%d%d%d", &op, &ql, &qr);
if(op == )
{
sum = ;
query();
printf("%lld\n", sum);
}
else
{
update();
}
}
return Accepted;
}