您的位置:首页 > 其它

蓝桥网 算法训练 操作格子

2016-11-09 20:35 309 查看
问题描述

有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

这就是一道线段树的最基础的模板题

AC代码:

# include <stdio.h>
# include <iostream>
# include <string.h>
# include <algorithm>
using namespace std;
typedef long long int ll;
int a[100010], r1[4*100010], r2[4*100010];
int ans1, ans2, index[4*100010];
void update1(int root, int l, int r, int cur, int add){
r1[root]=r1[root]+add;
if(l==r){
return;
}
int mid=(l+r)/2;
if(cur<=mid){
update1(root*2, l, mid, cur, add);
}
if(cur>=mid+1){
update1(root*2+1, mid+1, r, cur, add);
}
return;
}
void update2(int k, int v){
r2[k]=v;
k=k/2;
while(k>0){
r2[k]=max(r2[k*2], r2[2*k+1]);
k=k/2;
}
return;
}
void query1(int root, int l, int r, int L, int R){
if(l>=L&&R>=r){
ans1=ans1+r1[root];
return;
}
int mid=(l+r)/2;
if(mid>=L){
query1(root*2, l, mid, L, R);
}
if(mid+1<=R){
query1(root*2+1, mid+1, r, L, R);
}
return;
}
void init(int root, int l, int r){
if(l==r){
index[l]=root;
return;
}
int mid=(l+r)/2;
init(root*2, l, mid);
init(root*2+1, mid+1, r);
}
void query2(int root, int l, int r, int L, int R){
if(l>=L&&R>=r){
if(r2[root]>ans2){
ans2=r2[root];
}
return;
}
int mid=(l+r)/2;
if(mid>=L){
query2(root*2, l, mid, L, R);
}
if(mid+1<=R){
query2(root*2+1, mid+1, r, L, R);
}
return;
}
int main(){
int i, j, k;
int m, n, x, y, p;
scanf("%d%d", &n, &m);
for(i=1; i<=n; i++){
scanf("%d", &a[i]);
}
memset(r2, -1, sizeof(r2));
init(1, 1, n);
for(i=1; i<=n; i++){
update1(1, 1, n, i, a[i]);
update2(index[i], a[i]);
}
for(i=1; i<=m; i++){
scanf("%d%d%d", &p, &x, &y);
if(p==1){
update1(1, 1, n, x, y-a[x]);
a[x]=y;
update2(index[x], y);
}
else{
if(p==2){
ans1=0;
query1(1, 1, n, x, y);
printf("%d\n", ans1);
}
else{
ans2=-1;
query2(1, 1, n, x, y);
printf("%d\n", ans2);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: