题目链接:https://www.luogu.com.cn/problem/P3332
思路:我们区间修改用一个线段树维护就可以了。
#include <bits/stdc++.h> using namespace std; #define LL long long #define mid (l+r>>1) LL a[200000+10], sum[50000*4+10], laz[50000*4+10], rec[50000*4+10]; void BT(LL i, LL l, LL r){ sum[i]=laz[i]=rec[i]=0; if(l==r){ sum[i]=a[l]; return ; } BT(i<<1, l, mid); BT((i<<1)+1, mid+1, r); sum[i]=sum[i<<1]+sum[(i<<1)+1]; } void pushdown(LL i, LL l, LL r){ if(rec[i]){//清空线段树 rec[i]=0; laz[i<<1]=laz[(i<<1)+1]=sum[i<<1]=sum[(i<<1)+1]=0; rec[(i<<1)]=rec[(i<<1)+1]=1; } if(laz[i]){ laz[(i<<1)]+=laz[i]; laz[(i<<1)+1]+=laz[i]; sum[(i<<1)]+=laz[i]*(mid-l+1); sum[(i<<1)+1]+=laz[i]*(r-mid); laz[i]=0; } } void add(LL i, LL l, LL r, LL L, LL R, LL v){ if(l==L&&r==R){ laz[i]+=v; sum[i]+=v*(r-l+1); return ; } if(laz[i]||rec[i]) pushdown(i, l, r); if(R<=mid) add(i<<1, l, mid, L, R, v); else if(L>mid) add((i<<1)+1, mid+1, r, L, R, v); else add(i<<1, l, mid, L, mid, v), add((i<<1)+1, mid+1, r, mid+1, R, v); sum[i]=sum[i<<1]+sum[(i<<1)+1]; } LL query(LL i, LL l, LL r, LL L, LL R){ if(l==L&&r==R){ return sum[i]; } if(laz[i]||rec[i]) pushdown(i, l, r); if(R<=mid) return query(i<<1, l, mid, L, R); if(L>mid) return query((i<<1)+1, mid+1, r, L, R); return query(i<<1, l, mid, L, mid)+query((i<<1)+1, mid+1, r, mid+1, R); } struct node{ LL x, y, type, l, r, k, id; //值 添加/删除 查询/修改 区间 第k大 询问数 }q[100000+5], q1[100000+5], q2[100000+5]; LL tot, totx, n, m, ans[100000+5]; void solve(LL ql, LL qr, LL l, LL r){ if(ql>qr) return ; if(l==r){ for(LL i=ql; i<=qr; i++){ if(q[i].type==2){ ans[q[i].id]=l; } } return ; } rec[1]=1, laz[1]=sum[1]=0;//清空线段树 LL t1=0, t2=0; for(LL i=ql; i<=qr; i++){ if(q[i].type==1){ if(q[i].x>mid){//第k大 add(1, 1, n, q[i].l, q[i].r, q[i].y); q2[t2++]=q[i]; } else{ q1[t1++]=q[i]; } } else{ LL tt=query(1, 1, n, q[i].l, q[i].r); if(tt<q[i].k){ q[i].k-=tt; q1[t1++]=q[i]; } else{ q2[t2++]=q[i]; } } } for(LL i=0; i<t1; i++) q[ql+i]=q1[i]; for(LL i=0; i<t2; i++) q[ql+t1+i]=q2[i]; solve(ql, ql+t1-1, l, mid); solve(ql+t1, qr, mid+1, r); } int main(){ tot=0, totx=0; scanf("%lld%lld", &n, &m); BT(1, 1, n); LL k, x, y, v; for(LL i=1; i<=m; i++){ scanf("%lld%lld%lld%lld", &k, &x, &y, &v); if(k==1){ q[++tot].x=v, q[tot].y=1, q[tot].type=1, q[tot].l=x, q[tot].r=y; } else{ q[++tot].type=2, q[tot].k=v, q[tot].l=x, q[tot].r=y, q[tot].id=++totx; } } solve(1, m, -n, n); for(LL i=1; i<=totx; i++){ printf("%lld\n", ans[i]); } return 0; }