有一列数,(都是2^63范围内的并且都大于0的整数),现在呢有一些操作, 操作 0 可以把区间LR内的所有数都变成它的平方根数(是取整后的),操作 1 可以就是求区间LR内的和了。
分析:因为这个操作是把一个数变成平方根,所以显得略棘手,不过如果仔细演算的话会发现一个2^64数的平方根开8次也就变成了 1,所以也更新不了多少次,所以可以每次更新到底。、
#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
#define Lson root<<1,L,tree[root].Mid()
#define Rson root<<1|1,tree[root].Mid()+1,R
const int maxn = 100005;
struct Tree
{
int L, R;
long long sum;
int Mid(){return (L+R)/2;}
int Len(){return (R-L+1);}
}tree[maxn*4];
long long val[maxn];
void Build(int root, int L, int R)
{
tree[root].L = L, tree[root].R = R;
if(L == R)
{
tree[root].sum = val[L];
return ;
}
Build(Lson);
Build(Rson);
tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
}
void Insert(int root, int L, int R)
{
if(tree[root].Len() == tree[root].sum)
return ;
if(tree[root].L == tree[root].R)
{
tree[root].sum = (long long)sqrt(tree[root].sum*1.0);
return ;
}
if(R <= tree[root].Mid())
Insert(root<<1, L, R);
else if(L > tree[root].Mid())
Insert(root<<1|1, L, R);
else
{
Insert(Lson);
Insert(Rson);
}
tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
}
long long Query(int root, int L, int R)
{
if(tree[root].L == L && tree[root].R == R)
return tree[root].sum;
if(R <= tree[root].Mid())
return Query(root<<1, L, R);
else if(L > tree[root].Mid())
return Query(root<<1|1, L, R);
else
return Query(Lson)+Query(Rson);
}
int main()
{
int i, N, M, t=1;
while(scanf("%d", &N) != EOF)
{
for(i=1; i<=N; i++)
scanf("%lld", &val[i]);
Build(1, 1, N);
scanf("%d", &M);
int c, a, b;
long long ans;
printf("Case #%d:\n", t++);
while(M--)
{
scanf("%d%d%d", &c, &a, &b);
if(a > b)swap(a, b);
if(c == 0)
Insert(1, a, b);
else
{
ans = Query(1, a, b);
printf("%lld\n", ans);
}
}
printf("\n");
}
return 0;
}