首页 > 代码库 > 线段树单点更新区间最大值 hdoj1754I Hate It
线段树单点更新区间最大值 hdoj1754I Hate It
题目:hdoj1754 I Hate It
分析:更新的话,建树的时候保存叶子编号的的节点信息,然后从下往上更新就ok。
求和的话,从根节点开始,然后找在根的左边还是右边,然后递归找一个所有中的最大值即可、
代码:
#include <cstdio> #include <algorithm> #include <iostream> using namespace std; const int N = 205000; struct Node { int l,r; int sum; }; Node tree[4*N]; int a[N]; int fa[N]; void build(int l,int r,int v) { tree[v].l=l; tree[v].r=r; if(l==r) { fa[l]=v; tree[v].sum=a[l]; return ; } int mid=(l+r)>>1; build(l,mid,v*2); build(mid+1,r,v*2+1); tree[v].sum=max(tree[v+v].sum,tree[v+v+1].sum); } void update(int t,int p,int x) { if(tree[t].sum<p) tree[t].sum=p; if(t==1) return ; update(t/2,p,x); } int queue(int a,int b,int v) { if(tree[v].l==a&&tree[v].r==b) { return tree[v].sum; } int mid=(tree[v].l+tree[v].r)>>1; if(b<=mid) return queue(a,b,v+v); else if(a>mid) return queue(a,b,v+v+1); else return max(queue(a,mid,v*2),queue(mid+1,b,v*2+1)); } int main() { //freopen("a.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,n,1); while(m--) { char c; int x,y; scanf("%*c%c",&c); scanf("%d%d",&x,&y); if(c=='Q') printf("%d\n",queue(x,y,1)); else if(c=='U') update(fa[x],y,x); } } return 0; }
线段树单点更新区间最大值 hdoj1754I Hate It
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。