hdu 1698 Just a Hook(线段树区区)

来源:互联网 发布:javascript实战 源码 编辑:程序博客网 时间:2024/04/29 16:21

题目链接:   http://acm.hdu.edu.cn/showproblem.php?pid=1698

题目大意:   给出初试值都为1的区间[1,n]

                  有M次操作,每次操作表示将[a,b]的值全部替换成c

                  最后输出总值的大小

解题思路:  线段树的区间更新,区间查询

                 这道题是线段树从点更新到区间更新的过渡题

                 用到lazy的思想,把每次只更新到[a,b]区间,而不会继续往下更新

                 什么时候再往下更新呢?等下一次查询或者更新到[a,b]区间之间时再把上次标记的更新

                 更新时间复杂度O(logN),查询时间复杂度O(logN)

#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 100100#define MID(a,b) (a+b)>>1#define L(a) a<<1#define R(a) (a<<1|1)typedef struct{    int left,right;    int sum,add;    //add是lazy的标记}Node;Node Tree[MAX<<2];void Build(int t,int l,int r)      //以1根结点建立线段树[l,r]{    Tree[t].left=l,Tree[t].right=r;    if(Tree[t].left==Tree[t].right)    {        Tree[t].add=0;      //初始化为0        Tree[t].sum=1;        return ;    }    int mid=MID(Tree[t].left,Tree[t].right);    Build(L(t),l,mid);    Build(R(t),mid+1,r);}void Insert(int t,int l,int r,int m)  //向以t为根结点,l为左子树,r为右子树的结点插入m{    if(Tree[t].left==l&&Tree[t].right==r)    {        Tree[t].add=m;       //每次到区间就更新lazy,并且退出        Tree[t].sum=(r-l+1)*m;        return ;    }    int mid=MID(Tree[t].left,Tree[t].right);    if(Tree[t].add!=0)       //如果此结点有上次未更新的lazy,则继续往下更新    {        Tree[L(t)].sum=(Tree[L(t)].right-Tree[L(t)].left+1)*Tree[t].add;        Tree[R(t)].sum=(Tree[R(t)].right-Tree[R(t)].left+1)*Tree[t].add;        Tree[L(t)].add=Tree[t].add;   //往下更新        Tree[R(t)].add=Tree[t].add;   //往下更新        Tree[t].add=0;      //标记此lazy以更新    }    if(l>mid)    {        Insert(R(t),l,r,m);    }    else if(r<=mid)    {        Insert(L(t),l,r,m);    }    else    {        Insert(L(t),l,mid,m);        Insert(R(t),mid+1,r,m);    }    Tree[t].sum=Tree[L(t)].sum+Tree[R(t)].sum;  //结点的值=左子树的值+右子树的值}int main(){    int i1,i,n,m,a,b,c,t;    scanf("%d",&t);    for(i1=1;i1<=t;i1++)    {        memset(Tree,0,sizeof(Tree));        scanf("%d%d",&n,&m);        Build(1,1,n);        for(i=1;i<=m;i++)        {            scanf("%d%d%d",&a,&b,&c);            Insert(1,a,b,c);        }        printf("Case %d: The total value of the hook is %d.\n",i1,Tree[1].sum);    }    return 0;}


注:原创文章,转载请注明出处

原创粉丝点击