hdu 1556 线段树

来源:互联网 发布:linux打包解包 编辑:程序博客网 时间:2024/06/06 02:31

题目链接


本来做了个稍微难的线段树区间更新,发现自己还是太菜,感谢前人思路
裸的区间更新
这道题有点不一样,懒惰标记可以在最后向下增加


#include <string.h>#include <stdio.h>#define max(a,b) a>b?a:b#define  N  1005#include<iostream>using namespace std;struct node {    int l,r,sum,n,az;} t[400000];int n,m;void build (int i,int l,int r) {    t[i].l=l;    t[i].r=r;    t[i].sum=0;    if(l==r) {        return;    }    int mid=(l+r)/2;    build(i*2,l,mid);    build(i*2+1,mid+1,r);}void update(int i,int l,int r) {    if(t[i].l==l&&t[i].r==r) {//这里是核心,类似懒惰标记,在中序遍历时向下附加        t[i].sum+=1;        return ;    }    int mid=(t[i].l+t[i].r)/2;    if(r<=mid)        update(i*2,l,r);    else if(l>mid)        update(i*2+1,l,r);    else {        update(i*2,l,mid);        update(i*2+1,mid+1,r);    }}void sum(int i) {//二叉树中序遍历    if(t[i].l==t[i].r) {        m++;        printf("%d",t[i].sum);        if(m!=n)printf(" ");        return ;    }    t[i*2].sum+=t[i].sum;    t[i*2+1].sum+=t[i].sum;    sum(i*2);    sum(i*2+1);}int main() {    while(cin>>n&&n) {        build(1,1,n);        for(int j=0; j<n; j++) {            int x,y;            scanf("%d%d",&x,&y);            update(1,x,y);        }        m=0;        sum(1);        printf("\n");    }    return 0;}


1 0