蓝桥网 算法训练 操作格子
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代码:
有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; }
相关文章推荐