题目大意:对区间的数开方,并向下取整。
题目有一个坑点,会出现左边大于右边,然后需要交换左右,而不是不处理。坑!
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 100005
#define ls rt<<1
#define rs ls|1
#define m (l+r)>>1
long long sum[MAX << 2];
bool tg[MAX << 2];
void uprt(int rt)
{
tg[rt] = (tg[rs] || tg[ls]);
sum[rt] = sum[ls] + sum[rs];
}
void updata(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
{
if (!tg[rt])
{
return;
}
}
if (l == r)
{
sum[rt] = floor(sqrt(sum[rt]));
if (sum[rt]<=1)
tg[rt] = false;
return;
}
int mid = m;
if (L <= mid)
updata(L, R, l, mid, ls);
if (mid < R)
updata(L, R, mid + 1, r, rs);
uprt(rt);
}
long long query(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
{
return sum[rt];
}
int mid = m;
long long ans = 0;
if (L <= mid)
ans = query(L, R, l, mid, ls);
if (mid < R)
ans += query(L, R, mid + 1, r, rs);
return ans;
}
void build(int l, int r, int rt)
{
if (l == r)
{
scanf("%lld", &sum[rt]);
tg[rt] = 1;
if (sum[rt] <= 1)
tg[rt] = 0;
return;
}
int mid = m;
build(l, mid, ls);
build(mid + 1, r, rs);
uprt(rt);
}
int main()
{
int icase = 1;
int n;
while (~scanf("%d", &n))
{
build(1, n, 1);
int k, a, b, c;
cin >> k;
printf("Case #%d:\n",icase++);
while (k--)
{
scanf("%d%d%d", &a, &b, &c);
if (b > c)
{
b = b + c;
c = b - c;
b = b - c;
}
if (a == 0)
{
updata(b, c, 1, n, 1);
}
else
{
printf("%lld\n", query(b, c, 1, n, 1));
}
}
puts("");
}
}