您的位置:首页 > 其它

蓝桥杯-操作格子(线段树)

2015-02-20 22:37 351 查看
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
#define ll __int64
#define INF 0x3fffffff
using namespace std;

struct Node
{
int l,r;
int Max,Sum;
int Mid(){
return (l+r)/2;
}
}tree[400000];

void BuildTree(int root,int l,int r)
{
tree[root].Max=-INF;
tree[root].Sum=0;
tree[root].l=l;
tree[root].r=r;
if(l!=r)
{
BuildTree(2*root+1,l,(l+r)/2);
BuildTree(2*root+2,(l+r)/2+1,r);
}
}

void Insert(int root,int i,int v)
{
if(tree[root].l==tree[root].r)
{
tree[root].Max=tree[root].Sum=v;
return;
}
if(i<=tree[root].Mid())
{
Insert(2*root+1,i,v);
}
else
{
Insert(2*root+2,i,v);
}
tree[root].Max=max(tree[2*root+1].Max,tree[2*root+2].Max);
tree[root].Sum=tree[2*root+1].Sum+tree[2*root+2].Sum;
}

int QuerySum(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 QuerySum(2*root+1,l,r);
}else if(l>tree[root].Mid()){
return QuerySum(2*root+2,l,r);
}else{
return QuerySum(2*root+1,l,tree[root].Mid())+QuerySum(2*root+2,tree[root].Mid()+1,r);
}
}

int QueryMax(int root,int l,int r)
{
if(tree[root].l==l&&tree[root].r==r){
return tree[root].Max;
}
if(r<=tree[root].Mid()){
return QueryMax(2*root+1,l,r);
}else if(l>tree[root].Mid()){
return QueryMax(2*root+2,l,r);
}else{
return max(QueryMax(2*root+1,l,tree[root].Mid()),QueryMax(2*root+2,tree[root].Mid()+1,r));
}
}

int main()
{
//freopen("d:\\Test.txt","r",stdin);
int n,m;
cin>>n>>m;
BuildTree(0,1,n);
for(int i=1;i<=n;i++)
{
int value;
cin>>value;
Insert(0,i,value);
}
for(int i=0;i<m;i++)
{
int p,x,y;
cin>>p>>x>>y;
if(p==1){
Insert(0,x,y);
}else if(p==2){
cout<<QuerySum(0,x,y)<<endl;
}else if(p==3){
cout<<QueryMax(0,x,y)<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: