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
| #include <cstdio> #include <cstring> #include <climits> #include <cstdint> #include <algorithm>
const int maxn=5e4+1000;
int bl[maxn],br[maxn],cntl,cntr;
template<class T>inline T max(T a,T b){return a<b?b:a;} template<class T>inline T min(T a,T b){return a<b?a:b;}
struct Node { int ls,rs; int64_t siz,tag; }T[maxn*300];
int root[maxn<<3],cnt;
inline int _modify(int L,int R,int rt,int l,int r) { if (!rt) rt=++cnt; T[rt].siz+=min(R,r)-max(L,l)+1; if (L<=l && R>=r) return T[rt].tag++,rt; int mid=(l+r)>>1; if (L<=mid) T[rt].ls=_modify(L,R,T[rt].ls,l,mid); if (R> mid) T[rt].rs=_modify(L,R,T[rt].rs,mid+1,r); return rt; }
inline int64_t _query(int L,int R,int rt,int l,int r,int64_t add=0) { if (!rt) rt=++cnt; if (L<=l && R>=r) return T[rt].siz+add*(r-l+1); int mid=(l+r)>>1; int64_t tot=0; if (L<=mid) tot+=_query(L,R,T[rt].ls,l,mid,add+T[rt].tag); if (R> mid) tot+=_query(L,R,T[rt].rs,mid+1,r,add+T[rt].tag); return tot; }
inline void modify(int x,int L,int R,int l,int r,int o,int n) { root[o]=_modify(L,R,root[o],1,n); if (l==r) return; int mid=(l+r)>>1; if (x<=mid) modify(x,L,R,l,mid,o<<1,n); else modify(x,L,R,mid+1,r,o<<1|1,n); }
inline int query(int L,int R,int64_t k,int l,int r,int o,int n) { if (l==r) return l; int mid=(l+r)>>1; int64_t rnk=_query(L,R,root[o<<1],1,n,0); if (k<=rnk) return query(L,R,k,l,mid,o<<1,n); else return query(L,R,k-rnk,mid+1,r,o<<1|1,n); }
int64_t sumv[maxn<<2],tag[maxn<<2]; #define ls l,mid,o<<1 #define rs mid+1,r,o<<1|1
inline void pushdown(int o,int len) { sumv[o<<1]+=tag[o]*(len-(len>>1)); sumv[o<<1|1]+=tag[o]*(len>>1); tag[o<<1]+=tag[o];tag[o<<1|1]+=tag[o]; tag[o]=0; }
inline void pushup(int o){sumv[o]=sumv[o<<1]+sumv[o<<1|1];}
inline void add(int L,int R,int c,int l,int r,int o) { if (L<=l && R>=r) return (void)(sumv[o]+=c*(r-l+1),tag[o]+=c); pushdown(o,r-l+1); int mid=(l+r)>>1; if (L<=mid) add(L,R,c,ls); if (R> mid) add(L,R,c,rs); pushup(o); }
inline int64_t query(int L,int R,int l,int r,int o) { if (L<=l && R>=r) return sumv[o]; pushdown(o,r-l+1); int mid=(l+r)>>1; int64_t tot=0; if (L<=mid) tot+=query(L,R,ls); if (R> mid) tot+=query(L,R,rs); return tot; }
inline int query(int L,int R,int64_t k,int n) { k=query(L,R,1,n,1)-k+1; return query(L,R,k,1,n*2+2,1,n)-n-1; }
inline void modify(int l,int r,int c,int n) { add(l,r,1,1,n,1); modify(c+n+1,l,r,1,n*2+2,1,n); }
int main() { int n,m; scanf("%d%d",&n,&m); int64_t c; for (int i=1,a,b,opt;i<=m;++i) { scanf("%d%d%d%lld",&opt,&a,&b,&c); if (opt&1) modify(a,b,c,n); else printf("%d\n",query(a,b,c,n)); } }
|