蓝桥杯_法训练—操作格子(线段树点更新与区间查询)
来源:互联网 发布:甜虾 知乎 编辑:程序博客网 时间:2024/06/05 13:21
Description
有n个格子,从左到右放成一排,编号为1-n。
共有m次操作,有3种操作类型:
1.修改一个格子的权值,
2.求连续一段格子权值和,
3.求连续一段格子的最大值。
对于每个2、3操作输出你所求出的结果。
Input
多组测试数据
第一行2个整数n,m。
接下来一行n个整数表示n个格子的初始权值。
接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。
Output
每组测试数据输出有若干行,行数等于p=2或3的操作总数。
每行1个整数,对应了每个p=2或3操作的结果。
Sample Input
4 31 2 3 42 1 31 4 33 1 4
Sample Output
63
题意很明确,就是线段树的单点更新,也没有什么坑,只要注意一些细节就好,数组也不是很大,好过。
【代码】
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int N=100010;int m,n;int a[N],s,maxm;struct tree{ int l,r,sum,maxn;}Node[N*4];int max(int x,int y){ return x>y?x:y;}void build_tree(int ans,int ll,int rr){ if(ll == rr) { Node[ans].l =Node[ans].r = ll; Node[ans].sum = Node[ans].maxn= a[ll]; return ; } int mid = (ll + rr )>>1; Node[ans].l = ll; Node[ans].r = rr; build_tree(ans<<1,ll,mid); build_tree(ans<<1|1,mid+1,rr); Node[ans].sum = Node[ans<<1].sum + Node[ans<<1|1].sum; Node[ans].maxn = max(Node[ans<<1].maxn , Node[ans<<1|1].maxn);}void update(int ans,int w,int value){ if(Node[ans].l == w&& Node[ans].r == w ) { Node[ans].sum= value; Node[ans].maxn = value; return ; } int mid = (Node[ans].l+Node[ans].r)>>1; if(w<=mid) { update(ans<<1,w,value); } else { update(ans<<1|1,w,value); } Node[ans].sum = Node[ans<<1].sum + Node[ans<<1|1].sum; Node[ans].maxn = max(Node[ans<<1].maxn,Node[ans<<1|1].maxn);}void query(int ans,int ll,int rr){ int mid = (Node[ans].l+Node[ans].r)>>1; if(Node[ans].l== ll&& Node[ans].r== rr) { s+=Node[ans].sum; return ; } if(rr<=mid) { query(ans<<1,ll,rr); } else if(ll>mid) { query(ans<<1|1,ll,rr); } else { query(ans<<1,ll,mid); query(ans<<1|1,mid+1,rr); }}int query_max(int ans,int ll,int rr){ int mid = (Node[ans].l+Node[ans].r)>>1; if(Node[ans].l == ll && Node[ans].r == rr) { return Node[ans].maxn; } if(Node[ans].l==Node[ans].r) return 0; if(rr<=mid) { query_max(ans<<1,ll,rr); } else if(ll>mid) query_max(ans<<1|1,ll,rr); else { return max(query_max(ans<<1,ll,mid),query_max(ans<<1|1,mid+1,rr)); } //printf("%d\n",maxm);}int main(){ while(~scanf("%d%d",&m,&n)){ for(int i=1;i<=m;i++) scanf("%d",&a[i]); build_tree(1,1,m); while(n--) { int x,aa,bb; scanf("%d",&x); if(x==1) { scanf("%d%d",&aa,&bb); update(1,aa,bb); } else if(x==2) { s=0; scanf("%d%d",&aa,&bb); query(1,aa,bb); printf("%d\n",s); } else { scanf("%d%d",&aa,&bb); printf("%d\n",query_max(1,aa,bb)); } } }}
代码写的还不熟练,有的地方比较繁琐,不过我觉得这样反而更容易懂。
阅读全文
1 0
- 蓝桥杯_法训练—操作格子(线段树点更新与区间查询)
- 蓝桥杯算法训练_格子操作_线段树_区间和与区间最值
- 蓝桥杯算法训练——操作格子(线段树+单点更新+区间求和+求最大值)
- 蓝桥杯 算法训练 操作格子 (线段树)
- 算法训练 操作格子 (线段树)
- 蓝桥杯 算法训练 操作格子 (线段树)
- 蓝桥杯 ALGO-8 算法训练 操作格子(线段树)
- HDOJ-1166(线段树点更新 + 区间查询)
- hdu1754 IHateIt (线段树点更新,区间查询)
- 线段树 (更新点查询区间)敌兵布阵
- 线段树 (更新区间查询点)Color the ball
- 蓝桥杯 操作格子(线段树更新,求和,求最大)
- 蓝桥杯 操作格子(线段树的更新)
- 算法训练 操作格子 线段树 单点修改,求区间和,区间最大值
- 线段树 (更新区间查询点)秋实大哥与小朋友
- 蓝桥杯_算法训练_操作格子
- hdu5493(线段树,离线操作,点修改,区间查询)
- Necklace (线段树单点更新+区间查询+离线操作)
- 剑指offer:(31)时间效率 :连续子数组最大和
- python初接触
- ubuntu下的jdk+eclipse安装
- [LeetCode] 143. Reorder List
- java 字符流相关的io操作原理分析
- 蓝桥杯_法训练—操作格子(线段树点更新与区间查询)
- PHP 5.3.0以上推荐使用mysqlnd驱动
- cocos 3.10 ccui.RichText修改计算行宽的计算方法
- tensorflow/tf.set_random_seed()
- 前向分步算法
- CI框架学习之--隐藏入口文件-index.php
- ajax的封装
- 关于深度学习中Dropout的理解
- 【转】Hexo的Next主题配置