您的位置:首页 > 其它

蓝桥杯 操作格子 线段树

2016-11-06 17:01 399 查看
第一次学习线段树

参考:http://blog.csdn.net/acmman/article/details/18631017 

#include <iostream>
#include <cmath>
using namespace std;

#define MAX_N 400010

struct Node{
int l,r;
int sum,maxium;
}node[MAX_N];

void build(int n,int l,int r)
{
node
.l=l;
node
.r=r;
node
.maxium=0;
node
.sum=0;

if (l==r) return;

int middle=(l+r)/2;
build(n*2,l,middle);
build(n*2+1,middle+1,r);
}

void Insert(int n,int v,int val)
{
node
.sum+=val;
node
.maxium=max(node
.maxium,val);

if (node
.l==node
.r) return;

int middle=(node
.l+node
.r)/2;
if (v<=middle) Insert(n*2,v,val);
else Insert(n*2+1,v,val);
}

void Modify(int n,int v,int val)
{
if (node
.l==node
.r)
{
node
.maxium=val;
node
.sum=val;
return;
}

int middle=(node
.l+node
.r)/2;
if (v<=middle) Modify(n*2,v,val);
else Modify(n*2+1,v,val);

node
.sum=node[n*2].sum+node[n*2+1].sum;
node
.maxium=max(node[n*2].maxium,node[n*2+1].maxium);
}

int PartSum(int n,int x,int y)
{
if (node
.l==x&&node
.r==y)
{
return node
.sum;
}
int middle=(node
.l+node
.r)/2;
if (y<=middle)
{
return PartSum(n*2,x,y);
}else if (x>middle)
{
return PartSum(n*2+1,x,y);
}else{
return PartSum(n*2,x,middle)+PartSum(n*2+1,middle+1,y);
}
}

int PartMax(int n,int x,int y)
{
if (node
.l==x&&node
.r==y)
{
return node
.maxium;
}
int middle=(node
.l+node
.r)/2;
if (y<=middle)
{
return PartMax(n*2,x,y);
}else if (x>middle)
{
return PartMax(n*2+1,x,y);
}else{
return max(PartMax(n*2,x,middle),PartMax(n*2+1,middle+1,y));
}
}

int main()
{
int n,m,val,p,x,y;
cin>>n>>m;
build(1,1,n);
for (int i=1;i<=n;i++)
{
cin>>val;
Insert(1,i,val);
}

while(m--){
cin>>p>>x>>y;
switch (p)
{
case 1:Modify(1,x,y); break;
case 2:cout<<PartSum(1,x,y)<<endl;break;
case 3:cout<<PartMax(1,x,y)<<endl;break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: