1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<cmath> using namespace std; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const int N=50000+100; struct SegmentTree { #define lson (now<<1) #define rson (now<<11) #define mid ((now_l+now_r)>>1) long long sum[N<<2]; int lazy[N<<2]; inline void update(int now) { sum[now]=sum[lson]+sum[rson]; } inline void pushdown(int now,int now_l,int now_r) { if(now_l!=now_r) { sum[lson]+=lazy[now]*(mid-now_l+1),sum[rson]+=lazy[now]*(now_r-mid); lazy[lson]+=lazy[now],lazy[rson]+=lazy[now]; } lazy[now]=0; } void Change(int l,int r,int w,int now,int now_l,int now_r) { pushdown(now,now_l,now_r); if(now_l>=l and now_r<=r) { lazy[now]=w,sum[now]+=1ll*w*(now_r-now_l+1); return; } if(l<=mid) Change(l,r,w,lson,now_l,mid); if(r>mid) Change(l,r,w,rson,mid+1,now_r); update(now); } long long Query(int l,int r,int now,int now_l,int now_r) { pushdown(now,now_l,now_r); if(now_l>=l and now_r<=r) return sum[now]; long long t_ans=0; if(l<=mid) t_ans+=Query(l,r,lson,now_l,mid); if(r>mid) t_ans+=Query(l,r,rson,mid+1,now_r); return t_ans; } #undef lson #undef rson #undef mid }sgt; struct OP { int l,r,no; long long w; }op1[N],op2[N]; struct DL { int l,r; vector <OP> op,qur; }mqueue[2*N]; int n,m,q,p,K=2*N-20; int ans[N]; int main() { freopen("3332.in","r",stdin); freopen("3332.out","w",stdout);
n=read(),m=read(); for(int i=1;i<=m;i++) { int op=read(); if(op==1) op2[++p].l=read(),op2[p].r=read(),op2[p].w=read(),op2[p].no=i; else op1[++q].l=read(),op1[q].r=read(),op1[q].w=read(),op1[q].no=i; }
int front=0,tail=0; mqueue[tail].l=-N,mqueue[tail].r=N; for(int i=1;i<=p;i++) mqueue[tail].op.push_back(op2[i]); for(int i=1;i<=q;i++) mqueue[tail].qur.push_back(op1[i]); tail++; memset(ans,0x3f,sizeof ans);
while(front!=tail) { if(mqueue[front].l==mqueue[front].r) { for(int i=0;i<int(mqueue[front].qur.size());i++) ans[mqueue[front].qur[i].no]=mqueue[front].l; } else if(mqueue[front].qur.size()>0) { int mid=int(floor((mqueue[front].l+mqueue[front].r)/2.0)),T=0; DL L,R; for(int i=0;i<int(mqueue[front].qur.size());i++) { for(;T<int(mqueue[front].op.size()) and mqueue[front].qur[i].no>mqueue[front].op[T].no;T++) { sgt.Change(mqueue[front].op[T].l,mqueue[front].op[T].r,mqueue[front].op[T].w>mid,1,1,n); if(mqueue[front].op[T].w>mid) R.op.push_back(mqueue[front].op[T]); else L.op.push_back(mqueue[front].op[T]); } long long t=sgt.Query(mqueue[front].qur[i].l,mqueue[front].qur[i].r,1,1,n); if(t>=mqueue[front].qur[i].w) R.qur.push_back(mqueue[front].qur[i]); else { mqueue[front].qur[i].w-=t; L.qur.push_back(mqueue[front].qur[i]); } } for(int i=0;i<T;i++) sgt.Change(mqueue[front].op[i].l,mqueue[front].op[i].r,-(mqueue[front].op[i].w>mid),1,1,n); L.l=mqueue[front].l,L.r=mid; R.l=mid+1,R.r=mqueue[front].r; mqueue[tail]=L,tail=(tail+1)%K; mqueue[tail]=R,tail=(tail+1)%K; } front=(front+1)%K; }
for(int i=1;i<=m;i++) if(ans[i]!=0x3f3f3f3f) printf("%d\n",ans[i]); return 0; }
|