zoukankan      html  css  js  c++  java
  • 树套树-权值线段树套区间线段树

    树套树留坑

    线段树套线段树:

    K大数查询

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=50000,M=50000*16*16;
    int n,m;
    int tot=0,rt[N*4+10],tl[M+10],tr[M+10],add[M+10];
    ll sum[M+10];
    int cnt=0;
    struct node
    {
        int val,id;
    }b[N+10];
    struct Q
    {
        int op,l,r;ll k;
    }q[N+10];
    template<typename T> inline void read(T &x)
    {
        x=0;int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        x=x*f;
    }
    bool cmp(node a,node b)
    {
        return a.val<b.val;
    }
    void ask_add(int &k,int l,int r,int ql,int qr)
    {
        if(!k) k=++tot;
        sum[k]+=min(r,qr)-max(l,ql)+1;
        if(ql<=l&&r<=qr)
        {
            add[k]++;
            return;
        }
        int mid=(l+r)>>1;
        if(ql<=mid) ask_add(tl[k],l,mid,ql,qr);
        if(qr>=mid+1) ask_add(tr[k],mid+1,r,ql,qr);
    }
    ll ask_sum(int &k,int l,int r,int ql,int qr,int d=0)
    {
        if(!k) return d*(min(r,qr)-max(l,ql)+1);
        if(ql<=l&&r<=qr) return sum[k]+d*(r-l+1);
        ll val=0;
        int mid=(l+r)>>1;
        if(ql<=mid) val+=ask_sum(tl[k],l,mid,ql,qr,d+add[k]);
        if(qr>=mid+1) val+=ask_sum(tr[k],mid+1,r,ql,qr,d+add[k]);
        return val;
    }
    void insert(int k,int l,int r,int ql,int qr,int d)
    {
        ask_add(rt[k],1,n,ql,qr);
        if(l==r) return;
        int mid=(l+r)>>1;
        if(d<=mid) insert(k<<1,l,mid,ql,qr,d);
        else insert(k<<1|1,mid+1,r,ql,qr,d);
    }
    int kth(int k,int l,int r,int ql,int qr,ll d)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        ll rcnt=ask_sum(rt[k<<1|1],1,n,ql,qr);
        if(rcnt<d) return kth(k<<1,l,mid,ql,qr,d-rcnt);
        else return kth(k<<1|1,mid+1,r,ql,qr,d);
    }
    inline void init()
    {
        sort(b+1,b+cnt+1,cmp);
        int i=1,j=1;
        while(j<=cnt)
        {
            b[i]=b[j];
            while(b[i].val==b[j].val&&j<=cnt) q[b[j++].id].k=i;
            ++i;
        }
        cnt=i-1;
    }
    int main()
    {
        read(n),read(m);
        rep(i,1,m)
        {
            read(q[i].op),read(q[i].l),read(q[i].r),read(q[i].k);
            if(q[i].op==1) b[++cnt].val=q[i].k,b[cnt].id=i;
        }
        init();
        rep(i,1,m)
        {
            if(q[i].op==1) insert(1,1,cnt,q[i].l,q[i].r,q[i].k);
            if(q[i].op==2) printf("%d
    ",b[kth(1,1,cnt,q[i].l,q[i].r,q[i].k)].val);
        }
        return 0;
    }
    
  • 相关阅读:
    java中的lamda表达式
    Arrays.sort()中Lambda表达式
    检索中的函数及不同范围的处理
    2014.6.24
    2014.6.23
    第六天培训
    第五天培训
    第四天培训
    第三天培训!
    第二天培训
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11423739.html
Copyright © 2011-2022 走看看