洛谷P3332 [ZJOI2013]K大數查詢 權值線段樹套區間線段樹_標記永久化
阿新 • • 發佈:2018-12-10
Code:
#include <cstdio> #include <algorithm> #include <string> #include <cstring> using namespace std; #define maxn 50005*256 #define ll long long int n,m,tree; struct SEGIN { int cnt; long long sumv[maxn],lazy[maxn]; int lson[maxn],rson[maxn]; void newnode(int &o) { o=++cnt;} void mark(int l,int r,int o,int delta) { sumv[o]+=delta*(r-l+1); lazy[o]+=delta; } void update(int l,int r,int &o,int L,int R) { if(l>r||l>R||r<L)return; if(!o) newnode(o); if(l>=L&&r<=R) { mark(l,r,o,1); return ;} int mid=(l+r)>>1; update(l,mid,lson[o],L,R), update(mid+1,r,rson[o],L,R); sumv[o]=sumv[lson[o]]+sumv[rson[o]]+(r-l+1)*lazy[o]; } long long query(int l,int r,int o,int L,int R) { if(l>r||l>R||r<L||!o)return 0; if(l>=L&&r<=R) return sumv[o]; int mid=(l+r)>>1; return query(l,mid,lson[o],L,R)+query(mid+1,r,rson[o],L,R)+lazy[o]*(min(R,r)-max(l,L)+1); } }segin; struct SegOUT { int root[maxn]; #define lson (o<<1) #define rson (o<<1)|1 void insert(int l,int r,int o,int k,int L,int R) { if(l>r)return; segin.update(1,n,root[o],L,R); if(l==r)return; int mid=(l+r)>>1; if(k<=mid) insert(l,mid,lson,k,L,R); else insert(mid+1,r,rson,k,L,R); } int query(int l,int r,int o,int L,int R,ll k) { if(l==r)return l; ll tmp=segin.query(1,n,root[rson],L,R); int mid=(l+r)>>1; if(k<=tmp) return query(mid+1,r,rson,L,R,k); else return query(l,mid,lson,L,R,k-tmp); } }segout; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int a,b,c;ll d; scanf("%d%d%d%lld",&a,&b,&c,&d); if(a==1) segout.insert(1,2*n,1,(int)d+n,b,c); else printf("%d\n",segout.query(1,2*n,1,b,c,d)-n); } return 0; }