给出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; }
时间: 2024-10-28 14:31:14