区间更新+lazy
I 操作 l-r 区间+c
C操作 l-r区间的最大值,并把最大值删除
线段树再加个记录最大值的位置即可
#include "stdio.h" #include "string.h" int ans,mark; struct node { int l,r,Max,mark,lazy; }data[400010]; void Pushdown(int k) { if (data[k].l==data[k].r) return ; if (data[k].lazy==0) return ; data[k*2].Max+=data[k].lazy; data[k*2].lazy+=data[k].lazy; data[k*2+1].Max+=data[k].lazy; data[k*2+1].lazy+=data[k].lazy; data[k].lazy=0; } void build(int l,int r,int k) { int mid; data[k].l=l; data[k].r=r; data[k].lazy=0; data[k].Max=0; data[k].mark=l; if (l==r) return ; mid=(l+r)/2; build(l,mid,k*2); build(mid+1,r,k*2+1); } void updata(int l,int r,int k,int op) { int mid; if (data[k].l==l && data[k].r==r) { data[k].lazy+=op; data[k].Max+=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); } if (data[k*2].Max>=data[k*2+1].Max) { data[k].Max=data[k*2].Max; data[k].mark=data[k*2].mark; } else { data[k].Max=data[k*2+1].Max; data[k].mark=data[k*2+1].mark; } } void query(int l,int r,int k) { int mid; if (data[k].l==l &&data[k].r==r) { if (data[k].Max>ans) { ans=data[k].Max; mark=data[k].mark; } return ; } mid=(data[k].l+data[k].r)/2; Pushdown(k); if (r<=mid) query(l,r,k*2); else if (l>mid) query(l,r,k*2+1); else { query(l,mid,k*2); query(mid+1,r,k*2+1); } } int main() { int n,m,l,r,c; char ch; while (scanf("%d%d",&n,&m)!=EOF) { if (n==0 && m==0) break; build(1,n,1); while (m--) { getchar(); scanf("%c",&ch); if (ch=='I') { scanf("%d%d%d",&l,&r,&c); updata(l,r,1,c); } else { ans=0; scanf("%d%d",&l,&r); query(l,r,1); printf("%d\n",ans); updata(mark,mark,1,-ans); } } } return 0; }
时间: 2024-10-14 02:53:33