洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化

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;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/10098922.html
今日推荐