线段树_HDU_4107

来源:互联网 发布:网络心理学的杂志 编辑:程序博客网 时间:2024/06/06 08:59
/*区间操作,最后输出区间内的值,每一个叶子节点线段树区间维护,但是又不能更新到根节点咋搞?将操作预处理存起来?有点不靠谱啊对每个节点来说,肯定是存值为伤害的值,但是究竟是+c还是+2c,这是一个问题当然,如果我们在区间里面,保存区间的最大伤害,最小伤害,那么,如何最小伤害>=p,则说明这个区间都在+2c如果区间最大伤害<p,则说明这个区间都是进行+c操作,但是,问题来了,如果区间既有+c又有+2c的,该如何选择呢?                                [1 5]                    [1 3]                       [4 5]            [1 2]           [3 3]       [4 4]               [5 5]      [1 1]   [2 2]现在[1,1]是5,[2,2]是10,对[1,2]的操作为+10,则,[1,1]需要+10,[2,2]加的是2*10,此时[1,2]最大值是10,最小值是5,哈哈傻逼,当然是不直接对[1,2]进行操作,直接继续分下去,对[1,1][2,2]两个子节点判定*//*卡时间啊,c++998ms,g++果断超*/#include<iostream>#include<cstdio>#include<cstring>#define Max(a,b) (a)>(b)?(a):(b)#define Min(a,b) (a)<(b)?(a):(b)const int maxn = 200020;using namespace std;int n,m,p;struct node{    int mx,mi,lazy;};node tree[maxn<<2];void work(int rt){    tree[rt].mi = Min(tree[rt<<1].mi,tree[rt<<1|1].mi);    tree[rt].mx = Max(tree[rt<<1].mx,tree[rt<<1|1].mx);}void workhard(int rt){    if(tree[rt].lazy)    {        tree[rt<<1].lazy += tree[rt].lazy;        tree[rt<<1|1].lazy += tree[rt].lazy;        tree[rt<<1].mi += tree[rt].lazy;        tree[rt<<1].mx += tree[rt].lazy;        tree[rt<<1|1].mi += tree[rt].lazy;        tree[rt<<1|1].mx += tree[rt].lazy;        tree[rt].lazy = 0;    }}void build(int l, int r, int rt){    tree[rt].mi = tree[rt].mx = tree[rt].lazy = 0;    if(l==r)return;    int mid = (l+r)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);}void updata(int a, int b,int c,int l, int r, int rt){    if(a<=l&&r<=b)    {        if(tree[rt].mi>=p)//最小值都复合加倍的条件,区间一定加倍        {            tree[rt].lazy += c<<1;            tree[rt].mi += c<<1;            tree[rt].mx += c<<1;            return;        }        if(tree[rt].mx<p)        {            tree[rt].lazy += c;            tree[rt].mi += c;            tree[rt].mx += c;            return;        }    }    int mid = (l+r)>>1;    workhard(rt);    if(mid>=a)        updata(a,b,c,l,mid,rt<<1);    if(mid<b)        updata(a,b,c,mid+1,r,rt<<1|1);    work(rt);}void print(int l ,int r, int rt){    if(l == r)    {        if(l!=1)            printf(" ");        printf("%d",tree[rt].mx);        return;    }    workhard(rt);    int mid = (l+r)>>1;    print(l,mid,rt<<1);    print(mid+1,r,rt<<1|1);}int main(){    int a,b,c;    while(scanf("%d%d%d",&n,&m,&p)!=EOF)    {        build(1,n,1);        while(m--)        {            scanf("%d%d%d",&a,&b,&c);            updata(a,b,c,1,n,1);        }        print(1,n,1);        printf("\n");    }    return 0;}/*10 6 101 10 52 9 63 8 74 7 85 6 95 5 10*/
0 0