位运算要比加减预算速度快
#include<stdio.h>
#include<algorithm>
using namespace std;
struct Node{
int l,r,sum,Max,Min;
}Tree[1000<<2]; //开的空间至少要4倍.左移两位就是4倍
void PushUp(int o)
{
Tree[o].sum=Tree[o*2].sum+Tree[o*2+1].sum;
Tree[o].Max=max(Tree[o*2].Max,Tree[o*2+1].Max);
Tree[o].Min=min(Tree[o*2].Min,Tree[o*2+1].Min);
}
void BuidTree(int o,int l,int r) //建树
{
Tree[o].l=l;
Tree[o].r=r;
if(l==r) //搜索到底层,输入数据
{
int t;
scanf("%d",&t);
Tree[o].Max=Tree[o].Min=Tree[o].sum=t;
return;
}
int mid=(l+r)>>1;
BuidTree(o*2,l,mid); //递归找左子树
BuidTree(o*2+1,mid+1,r); //递归找右子树
PushUp(o);
}
void UpDate(int o,int l,int r,int x,int y) //数据更新,将底层x节点值变为y
{
if(l==r)
{
Tree[o].Max=Tree[o].Min=Tree[o].sum=y;
return ;
}
int mid=(l+r)>>1;
if(x<=mid)
UpDate(o*2,l,mid,x,y);
else
UpDate(o*2+1,mid+1,r,x,y);
PushUp(o);
}
int QuerySum(int o,int l,int r,int x,int y) //x到y的和
{
if(l==x&&y==r)
return Tree[o].sum;
int mid=(l+r)>>1;
if(mid<x)
return QuerySum(o*2+1,mid+1,r,x,y);
else if(y<=mid)
return QuerySum(o*2,l,mid,x,y);
else
return QuerySum(o*2,l,mid,x,mid)+QuerySum(o*2+1,mid+1,r,mid+1,y);
}
int QueryMax(int o,int l,int r,int x,int y) //x到y最大
{
if(l==x&&y==r)
return Tree[o].Max;
int mid=(l+r)>>1;
if(mid<x)
return QueryMax(o*2+1,mid+1,r,x,y);
else if(y<=mid)
return QueryMax(o*2,l,mid,x,y);
else
return max(QueryMax(o*2,l,mid,x,mid),QueryMax(o*2+1,mid+1,r,mid+1,y));
}
int QueryMin(int o,int l,int r,int x,int y) //x到y最小
{
if(l==x&&y==r)
return Tree[o].Min;
int mid=(l+r)>>1;
if(mid<x)
return QueryMin(o*2+1,mid+1,r,x,y);
else if(y<=mid)
return QueryMin(o*2,l,mid,x,y);
else
return min(QueryMin(o*2,l,mid,x,mid),QueryMin(o*2+1,mid+1,r,mid+1,y));
}
int main()
{
int n,T,st,endd;
scanf("%d",&T); //T组数据
while(T--)
{
scanf("%d",&n); //n个数
scanf("%d%d",&st,&endd); //查询的起止点
BuidTree(1,1,n);
printf("%d\n",QuerySum(1,1,n,st,endd));
printf("%d\n",QueryMax(1,1,n,st,endd));
printf("%d\n",QueryMin(1,1,n,st,endd));
}
return 0;
}