题意:
给定一串数字,再给定两个操作:
0.查询 x 到 y的和
1.更新 x到 y的每个值 ,使其变为根号倍
Notice that the square root operation should be rounded down to integer.
将有可能变成的小树变为整数
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
long long a[100010];
long long ans;
struct TreeNode
{
long long num;
int left;
int right;
int ac;
}Tree[100010*4];
void Build(int i, int l , int r)
{
Tree[i].left=l;
Tree[i].right=r;
if(l==r)
{
Tree[i].num=a[l];
if(Tree[i].num==1)
Tree[i].ac=1;
else
Tree[i].ac=0;
return ;
}
int m=(l+r)/2;
Build(lson);
Build(rson);
Tree[i].num=Tree[i<<1].num+Tree[i<<1|1].num;
if(Tree[i*2].ac&&Tree[i*2+1].ac)
Tree[i].ac=1;
else Tree[i].ac=0;
}
void U(int i,int l,int r)
{
if(Tree[i].ac)return;
if(Tree[i].left==Tree[i].right)
{
Tree[i].num=floor(sqrt(Tree[i].num));
if(Tree[i].num==1)
Tree[i].ac=1;
return ;
}
int m=(Tree[i].left+Tree[i].right)>>1;
if(l>m)
{
U(i<<1|1,l,r);
}
else if(r<=m)
{
U(i<<1,l,r);
}
else
{
U(lson);
U(rson);
}
Tree[i].num=Tree[i<<1].num+Tree[i<<1|1].num;
if(Tree[i*2].ac&&Tree[i*2+1].ac)
Tree[i].ac=1;
}
void Q(int i, int l ,int r)
{
if(l==Tree[i].left&&r==Tree[i].right)
{
ans+=Tree[i].num;
return ;
}
int m=(Tree[i].left+Tree[i].right)>>1;
if(r<=m)
{
Q(i<<1,l,r);
}
else if(l>m)
{
Q(i<<1|1,l,r);
}
else
{
Q(lson);
Q(rson);
}
}
int main()
{
int n;
int flag=0;
while(scanf("%d",&n)!=EOF)
{ flag++;
printf("Case #%d:\n",flag);
int i;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
Build(1,1,n);
int t;
scanf("%d",&t);
while(t--)
{
ans=0;
int d,x,y;
scanf("%d%d%d",&d,&x,&y);
if(x>y)
swap(x,y);
if(d==0)
{
U(1,x,y);
}
else
{Q(1,x,y);
printf("%lld\n",ans);
}
}
printf("\n");
}
return 0;
}