线段树区间修改和点修改 hdoj 1698(区间修改)、hdoj 1754(点修改)

简介: 这两题我都在之前做过,但并未通过,那次做的时候是刚开始接触线段树,现在有了一点点的了解,翻出以前的代码稍作修改就AC了。之前1698错误的原因是没有注意到位运算的优先级。

这两题我都在之前做过,但并未通过,那次做的时候是刚开始接触线段树,现在有了一点点的了解,翻出以前的代码稍作修改就AC了。之前1698错误的原因是没有注意到位运算的优先级。

//hdoj 1698
#include<stdio.h>
#include<string.h>
#define maxn 100010
struct node
{
    int l;
    int r;
    int mid;
    int val;
}tree[maxn<<2];
void buildtree(int o,int l,int r)
{
    tree[o].val = 1;
    tree[o].l = l;
    tree[o].r = r;
    tree[o].mid = (l + r)>>1;
    if(l == r)
        return ;
    else
    {
        buildtree(o<<1, l, tree[o].mid);
        buildtree((o<<1)+1, tree[o].mid + 1, r);
    }
}
void update(int o, int l, int r, int val)
{
    if(l == tree[o].l && r == tree[o].r)
    {
        tree[o].val = val;
        return ;
    }
    //递归边界,如果更新的边界和节点边界相同则返回
    if(tree[o].val != 0)
    {
        tree[o<<1].val = tree[o].val;
        tree[(o<<1)+1].val = tree[o].val;
        tree[o].val = 0;
    }
    //这个地方是为了表示tree[o]的两个节点的val值是不一样的
    //要更新的段无非三种情况,要么在l-mid段,要么在mid-r段,再么就是两端都存在的,分情况递归
    if(r <= tree[o].mid)
        update(o<<1, l, r, val);
    //这个是位于l-mid段的
    else if(l > tree[o].mid)
        update((o<<1)+1, l, r, val);
    //这个是位于mid-r段的
    else
    {
        update(o<<1, l, tree[o].mid, val);
        update((o<<1)+1, tree[o].mid + 1, r, val);
    }
    //两段都有的情况
}
int getsum(int o,int l,int r)
{
    if(tree[o].val > 0)
        return tree[o].val * (tree[o].r - tree[o].l + 1);
    //tree[o].val > 0 证明在tree[o].l到tree[o].r区间里面的val都是一样的,要获取的区间也属于该区间
    if(r <= tree[o].mid)
        return getsum(o * 2, l, r);
    //同 update() 也是分三种情况
    else if (l > tree[o].mid)
        return getsum((o<<1)+1, l, r);
    else
        return getsum(o<<1, l, tree[o].mid) + getsum((o<<1)+1, tree[o].mid, r);
}
int main()
{
    int t, n, i, j, op, x, y, z;
    scanf("%d",&t);
    for(i = 1;i <= t;i++)
    {
        scanf("%d",&n);
        buildtree(1, 1, n);
        scanf("%d",&op);
        while(op--)
        {
            scanf("%d%d%d",&x,&y,&z);
            update(1, x, y, z);
        }
        int ans = getsum(1,1,n);
        printf("Case %d: The total value of the hook is %d.\n",i,ans);
    }
    return 0;
}


//hdoj 1754
#include<stdio.h>
#include<string.h>
#define maxn 200005
struct node
{
  int l;
  int r;
  int mid;
  int max;
}tree[maxn<<2];
int arr[maxn];
int max(int a,int b)
{
  return a > b ? a : b;
}
void build(int o, int l, int r)
{
  tree[o].l = l;
  tree[o].r = r;
  tree[o].mid = (l + r)>>1;
  if(l == r)
    {
        tree[o].max = arr[l];
  return ;
    }
  build(o<<1, l, tree[o].mid);
  build((o<<1)+1, tree[o].mid + 1, r);
  tree[o].max = max(tree[o<<1].max, tree[(o<<1)+1].max);
}
void update(int o, int l, int r,int a, int val)
{
    tree[o].max = max(tree[o].max, val);
  if(tree[o].l == tree[o].r)
  {
  return ;
  }
  if(a <= tree[o].mid)
  update(o<<1,l,tree[o].mid,a,val);
  else
  update((o<<1)+1, tree[o].mid + 1, r, a, val);
}
int query(int o,int l,int r)
{
  if(l == tree[o].l && r == tree[o].r)
  return tree[o].max;
  if(r <= tree[o].mid)
  return query(o*2,l,r);
  if(l > tree[o].mid)
  return query((o<<1)+1, l, r);
  return max(query(o<<1, l, tree[o].mid),query((o<<1)+1, tree[o].mid+1, r));
}
int main()
{
  int n, m, i, t, a, b;
  char c;
  while(scanf("%d%d",&n,&m) != EOF)
  {
  for(i = 1;i <= n;i++)
  {
    scanf("%d",&arr[i]);
  }
  build(1,1,n);
  while(m--)
  {
      getchar();
    scanf("%c%d%d",&c,&a,&b);
    if(c == 'U')
    update(1,1,n,a,b);
    else
    printf("%d\n",query(1,a,b));
  }
  }
  return 0;
}


目录
相关文章
|
11月前
|
C++
线段树的单点修改
线段树的单点修改
59 0
|
11月前
|
C++
线段树的区间修改
线段树的区间修改
41 0
|
5月前
leetcode代码记录(平衡二叉树
leetcode代码记录(平衡二叉树
34 0
|
人工智能
51nod 1624 取余最长路 (set 二分)
51nod 1624 取余最长路 (set 二分)
66 0
51nod 1711 平均数(二分 + 树状数组好题)
51nod 1711 平均数(二分 + 树状数组好题)
94 0
|
机器学习/深度学习
HDU-2553,N皇后问题(DFS+回溯)
HDU-2553,N皇后问题(DFS+回溯)