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; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。