您的位置:首页 > 其它

算法训练 操作格子

2018-03-10 21:32 351 查看
问题描述有n个格子,从左到右放成一排,编号为1-n。
共有m次操作,有3种操作类型:
1.修改一个格子的权值,
2.求连续一段格子权值和,
3.求连续一段格子的最大值。
对于每个2、3操作输出你所求出的结果。
输入格式第一行2个整数n,m。
接下来一行n个整数表示n个格子的初始权值。
接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。
输出格式有若干行,行数等于p=2或3的操作总数。
每行1个整数,对应了每个p=2或3操作的结果。
样例输入4 3
1 2 3 4
2 1 3
1 4 3
3 1 4样例输出6
3数据规模与约定对于20%的数据n <= 100,m <= 200。
对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

思路:
线段树单点更新,维护区间和,区间最大值课题.

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;

const int maxn = 1e5+5;
int a[maxn];
int tree1[4*maxn],tree2[4*maxn];

void build(int l,int r,int d)
{
if ( l == r ){
tree1[d] = a[l];
tree2[d] = a[l];
return;
}

int mid = (l+r)/2;
build(l,mid,2*d);
build(mid+1,r,2*d+1);
tree1[d] = tree1[2*d]+tree1[2*d+1];
tree2[d] = max(tree2[2*d],tree2[2*d+1]);

return;
}

void update(int pos,int l,int r,int d,int num)
{
if ( l == r ){
tree1[d] = num;
tree2[d] = num;
return;
}

int mid = (l+r)/2;
if (pos <= mid) //左子树
update(pos,l,mid,2*d,num);
else //右子树
update(pos,mid+1,r,2*d+1,num);
tree1[d] = tree1[2*d]+tree1[2*d+1];
tree2[d] = max(tree2[2*d],tree2[2*d+1]);

return ;
}

int query(int l,int r,int L,int R,int d)
{
if (l == L && r == R){
return tree1[d];
}
int mid = (L+R)/2;
if (r <= mid){
return query(l,r,L,mid,2*d);
}
else if (l > mid)
return query(l,r,mid+1,R,2*d+1);
else //部分在左子树,部分在右子树
return query(l,mid,L,mid,2*d)+query(mid+1,r,mid+1,R,2*d+1);
}

int querymax(int l,int r,int L,int R,int d)
{
if (l == L && r == R){
return tree2[d];
}
int mid = (L+R)/2;
int m = 0;
if (r <= mid)
return max(querymax(l,r,L,mid,2*d),m);
else if (l > mid)
return max(querymax(l,r,mid+1,R,2*d+1),m);
else
return max(querymax(l,mid,L,mid,2*d),querymax(mid+1,r,mid+1,R,2*d+1));

}

int main()
{
int n,m,p,x,y;

cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> a[i];
//建树
build(1,n,1);

for(int i = 0; i < m; i++){
cin >> p >> x >> y;

if ( p == 1 ){
update(x,1,n,1,y);
}
else if ( p == 2 ){
int sum = query(x,y,1,n,1);
cout << sum << endl;
}
else{
int maxn = querymax(x,y,1,n,1);
cout << maxn << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: