hdu 1698 Just a hook 线段树 成段更新~~区间求和

来源:互联网 发布:学技术的软件 编辑:程序博客网 时间:2024/05/02 01:27

这道题很经典~~感觉挺有意思,可能是我自己花时间想了好久吧。。

线段树成段更新,区间求和;

我自己想的时候,曲折的成段更新,各种wrong 后来改了好久,结果TLE

然后参考了下 ~~~秒懂,感觉收获挺大的~这种成段更新的线段树就领会了。。

说一下题意: n个钩子,编号为1到n,然后m种操作,会将一段区间的钩子值变化, 

变化形式如:   x y 1;

                           x y 2;

                           x y 3;

三种形式,我们更新的时候不需要完全更新,,,这样说好像不太好理解。。

举个例子吧,取n 等于10,那么从1-10建树  build(1,1,10);。。。。那么我现在要把  1 到5 这个区间的值变为 3 ,那么我是不是要从1 到  5 依次改变这5 个钩子了呢???

如果这样做,那么线段树的优势没了,时间复杂度又上去了,所以我们不需要一个个的去改值,只需要 用一个 变量记录C记录下来, 等下次更新的时候再变化。。

现在看代码吧,相信会懂的,很容易理解;

代码如下:

#include <iostream>
#include <stdio.h>
#define N 800000
using namespace std;
struct node   //节点
{
 int l,r,c;   
}st[N];
void build(int v,int l,int r)  //建树
{
  st[v].l=l;
  st[v].r=r;
  st[v].c=1;                      //钩子都初始化为1
  if(l==r)return;
  int mid=(l+r)/2;
  build(2*v,l,mid);
  build(2*v+1,mid+1,r);  
}
void insert(int v,int l,int r,int d) //更新
{
  if(st[v].l==l&&st[v].r==r)   //找到这个区间后,不需要再往下找了
  {
    st[v].c=d;                        //记录改变的值 
    return;    
  }
  if(st[v].c!=-1)                  //当程序执行这一步的时候,说明上一步没执行,表示要找的区间是目前这个节点所表示区间的子区间,所以把目前这个节点的所有属性移交给左右孩

                                         //然后置c为-1. 

{    st[2*v].c=st[v].c;

    st[2*v+1].c=st[v].c;
    st[v].c=-1;
  }
  int mid=(st[v].l+st[v].r)/2;
  if(l>mid)
      insert(2*v+1,l,r,d);
  else if(r<=mid)
      insert(2*v,l,r,d);
  else 
     {
       insert(2*v,l,mid,d);
       insert(2*v+1,mid+1,r,d);   
     }
}
long long  getsum(int v)   //这就开始遍历
{
  if(st[v].c!=-1)                                   //如果不等于-1 ,说明这个节点的C值代表整个区间的类型
  {
     return st[v].c*(st[v].r-st[v].l+1); 
  }
  else                                                 //如果C等于-1,说明其属性移交了,顾继续遍历左右孩子。。
  {
    return  getsum(2*v)+getsum(2*v+1);
     
  }
}
int main()
{
 int t,n,m,test=0;
 scanf("%d",&t);
 while(t--)
 {
    test++;
    scanf("%d%d",&n,&m);
    build(1,1,n);
    int x,y,z;
    for(int i=0;i<m;i++)
    {
      scanf("%d%d%d",&x,&y,&z);
      insert(1,x,y,z);  
    }
    printf("Case %d: The total value of the hook is %lld.\n",test,getsum(1));
 }
 return 0;   
}

0 0
原创粉丝点击