hdoj 1698--Just a Hook 线段树练习

来源:互联网 发布:达芬奇调色 mac 编辑:程序博客网 时间:2024/06/10 20:38
/***********************************************Copyright:GlderAuthor:GlderDate:2013-08-03 14:54:46Destription:1、插线问题(成段更新)2、建树结构体中是需要多加个元素权值3、建树操作中注意A:    if(l == r)    {        s[root].num = 1;        s[root].x = 0;        cout<<"root: "<<root<<endl;        return;    }如果这样写,不能把所有s[root].x都更新一遍,出现wa;只需把s[root].x = 0;提到if语句外面即可ac,因为最后有个pushup语句可以保证能把每个num都更新到。B:    s[root].num = 1;    s[root].x = 0;    cout<<"root: "<<root<<endl;    if(l == r)    {        return;    }如果这样写,建树顺序如下:root:1 2 4 8 16 17 9 5 10 11 3 6 12 24 25 13 7 14 154、注意更新操作中要有注意更新时需要从父节点到子节点,这是此题要重点理解的内容。5、本题最后需要查询全部值的和,可以直接输出s[1].num,也可以直接使用query(1,1,n);***********************************************/#include<iostream>#include<cstdio>using namespace std;struct Segtree{    int left;    int right;    int num;    int x;//权值}s[100005<<2];void build(int root,int l,int r){    s[root].left = l;    s[root].right = r;    s[root].x = 0;    if(l == r)    {        s[root].num = 1;        return;    }    int m = (l+r)/2;    build(root<<1,l,m);    build(root<<1|1,m+1,r);    s[root].num = s[root<<1].num + s[root<<1|1].num;}void update(int root,int a,int b,int x){    int l = s[root].left;    int r = s[root].right;    if(a <= l && b >= r)    {        s[root].num = x*(r-l+1);        s[root].x = x;        return;    }    if(s[root].x)//把当前节点信息更新到叶子节点    {        int p = r - l + 1;        s[root<<1].x = s[root].x;        s[root<<1|1].x = s[root].x;        s[root<<1].num = (p - p/2)*s[root].x;        s[root<<1|1].num = (p/2)*s[root].x;        s[root].x = 0;    }    int m = (l + r)>>1;    if(a <= m)        update(root<<1,a,b,x);    if(b > m)        update(root<<1|1,a,b,x);    s[root].num = s[root<<1].num + s[root<<1|1].num;}int query(int root,int a,int b){    int l = s[root].left;    int r = s[root].right;    if(a == l && b == r)        return s[root].num;    int m = (l + r) >> 1;    int cnt = 0;    if(a <= m)        cnt += query(root<<1,a,b);    if(b > m)        cnt += query(root<<1|1,a,b);    return cnt;}int main(){    int t,n,q;    int x,y,c;    scanf("%d",&t);    int cas = 1;    while(t--)    {        scanf("%d",&n);        build(1,1,n);        scanf("%d",&q);        while(q--)        {            scanf("%d%d%d",&x,&y,&c);            update(1,x,y,c);        }        printf("Case %d: The total value of the hook is %d.\n",cas++,query(1,1,n));    }}