hdu4107(线段数的懒惰标记)
http://acm.hdu.edu.cn/showproblem.php?pid=4107
思路:在结构体中开max、min域,max、min用来标记某一段区间的最大最小值。在更新数据的时候,用区间的max\min去与p比较,如果整段区间都小于p,那么num+=c;如果min>=p,那么num+=2*c;这样,就不用每次都更新到最低端...........
#include<iostream>
using namespace std;
#define M 200005
struct
{
int l,r,num;
int max,min;
}tree[M*4];
int n,m,p;
void creat(int i,int l,int r)
{
int mid=(l+r)/2;
tree[i].l=l;
tree[i].r=r;
tree[i].num=0;
tree[i].max=0;
tree[i].min=0;
if(l==r)
return;
creat(i*2,l,mid);
creat(i*2+1,mid+1,r);
}
void updata(int i,int l,int r,int v)
{
int mid=(tree[i].l+tree[i].r)/2;
if(tree[i].l==l&&tree[i].r==r)
{
if(tree[i].min>=p)
{
tree[i].num+=2*v;
tree[i].max+=2*v;
tree[i].min+=2*v;
return ;
}
if(tree[i].max<p)
{
tree[i].num+=v;
tree[i].max+=v;
tree[i].min+=v;
return ;
}
}
if(tree[i].num!=0) //如果区间值不为0,则把区间值往下传递,因为num记录的是整段区间所要加的值
{
tree[i*2].num+=tree[i].num;
tree[i*2].max+=tree[i].num;
tree[i*2].min+=tree[i].num;
tree[i*2+1].num+=tree[i].num;
tree[i*2+1].min+=tree[i].num;
tree[i*2+1].max+=tree[i].num;
tree[i].num=0; //加完后,要将num清零,以免重复加..........
}
if(r<=mid)
updata(i*2,l,r,v);
else if(l>mid)
updata(i*2+1,l,r,v);
else
{
updata(i*2,l,mid,v);
updata(i*2+1,mid+1,r,v);
}
tree[i].max=tree[i*2].max>tree[i*2+1].max ? tree[i*2].max:tree[i*2+1].max; //更新区间的最大最小值,方便下一次判断
tree[i].min=tree[i*2].min<tree[i*2+1].min ? tree[i*2].min:tree[i*2+1].min;
}
void quest(int i)
{
if(tree[i].l==tree[i].r)
{
if(tree[i].l!=1)
printf(" ");
printf("%d",tree[i].num);
return;
}
if(tree[i].num!=0)
{
tree[i*2].num+=tree[i].num;
tree[i*2+1].num+=tree[i].num;
tree[i].num=0;
}
quest(i*2);
quest(i*2+1);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&p)>0)
{
creat(1,1,n);
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
updata(1,a,b,c);
}
quest(1);
printf("\n");
}
return 0;
}
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。

浙公网安备 33010602011771号