您的位置:首页 > 其它

HDU 4107 线段树

2014-11-03 17:39 190 查看
给出N个节点,M次操作,和p

每次操作 对l-r区间的每个节点+c,若节点值>=p,则加2*c;

结点存当前区间伤害最小值,最大值,以及lazy操作。更新到如果最小值大于等于P,或者最大值小于P为止。

#include "stdio.h"
#include "string.h"

struct node
{
int l,r,Min,Max,lazy;
} data[800010];
int p;

int Max(int a,int b)
{
if (a<b) return b;
else return a;
}

int Min(int a,int b)
{
if (a<b) return a;
else return b;
}

void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].Min=data[k].Max=data[k].lazy=0;

if (l==r) return ;

mid=(l+r)/2;

build(l,mid,k*2);
build(mid+1,r,k*2+1);
}

void Pushdown(int k)
{
if (data[k].l==data[k].r) return ;
if (data[k].lazy!=0)
{
data[k*2].lazy+=data[k].lazy;
data[k*2].Max+=data[k].lazy;
data[k*2].Min+=data[k].lazy;
data[k*2+1].lazy+=data[k].lazy;
data[k*2+1].Max+=data[k].lazy;
data[k*2+1].Min+=data[k].lazy;
data[k].lazy=0;
}
}
void updata(int l,int r,int k,int op)
{
int mid;
if (data[k].l==l && data[k].r==r)
{
if (data[k].Max<p)
{
data[k].lazy+=op;
data[k].Max+=op;
data[k].Min+=op;
return ;
}
if (data[k].Min>=p)
{
data[k].lazy+=2*op;
data[k].Max+=2*op;
data[k].Min+=2*op;
return ;
}

}

Pushdown(k);

mid=(data[k].l+data[k].r)/2;

if (r<=mid) updata(l,r,k*2,op);
else if (l>mid) updata(l,r,k*2+1,op);
else
{
updata(l,mid,k*2,op);
updata(mid+1,r,k*2+1,op);
}
data[k].Max=Max(data[k*2].Max,data[k*2+1].Max);
data[k].Min=Min(data[k*2].Min,data[k*2+1].Min);
}

void query(int k)
{
if(data[k].l==data[k].r)
{
if (data[k].l!=1)
printf(" %d",data[k].Max);
else
printf("%d",data[k].Max);
return ;
}
Pushdown(k);
query(k*2);
query(k*2+1);
}

int main()
{
int n,m,l,r,x;
while (scanf("%d%d%d",&n,&m,&p)!=EOF)
{
build(1,n,1);
while (m--)
{
scanf("%d%d%d",&l,&r,&x);
updata(l,r,1,x);
}
query(1);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: