• 主席树


     理解了 好久呀 (2个下午)

     直接上动态修改

     动态修改要先离线

     注意 查询的时候是 点的 左儿子的 总数 相减 !!!!!

     后面的 n,m ,cent好好区分一下

    #include <bits/stdc++.h>
    using namespace std;
    const int M = 5e5+7;
    const int N = 5e5+7;
    #define ri register int
    struct setdian{
        int l,r,k;
        bool op;
    }p[N * 40];
    int val[N * 40],b[N * 40],T[N * 40],q;
    int sum[N * 40],root[N * 40],lson[N * 40],rson[N * 40],ls[N * 40],rs[N * 40];
    int n,m,tim;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void build(int l,int r,int &cur)
    {
        cur=++tim;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(l,mid,lson[cur]);
        build(mid+1,r,rson[cur]);
    }
    void xiu(int l,int r,int pre,int &cur,int pos,int k)
    {
        cur=++tim;
        lson[cur]=lson[pre],rson[cur]=rson[pre];
        sum[cur]=sum[pre]+k;
        int mid=(l+r)>>1;
        if(l==r) return ;
        if(pos<=mid)
        {
            xiu(l,mid,lson[pre],lson[cur],pos,k);
        }
        else
        {
            xiu(mid+1,r,rson[pre],rson[cur],pos,k);
        }
    }
    void change(int x,int pos,int k)
    {
        while(x<=n)
        {
            xiu(1,q,T[x],T[x],pos,k);
            x+=lowbit(x);
        }
    }
    int cha(int l,int r,int pre,int cur,int k)
    {
        int ans=sum[lson[cur]]-sum[lson[pre]];////////////// 关键 
        int mid=(l+r)>>1;
        if(l==r) return l;
        for(ri i=1;i<=ls[0];i++)
        {
            ans-=sum[lson[ls[i]]];///////// 关键 
        }
        for(ri i=1;i<=rs[0];i++)
        {
            ans+=sum[lson[rs[i]]]; ///////////////////// 关键 
        }
        if(ans>=k)
        {
            for(ri i=1;i<=ls[0];i++)
            ls[i]=lson[ls[i]];
            for(ri i=1;i<=rs[0];i++)
            rs[i]=lson[rs[i]];
            return cha(l,mid,lson[pre],lson[cur],k);
        }
        else
        {
            for(ri i=1;i<=ls[0];i++)
            ls[i]=rson[ls[i]];
            for(ri i=1;i<=rs[0];i++)
            rs[i]=rson[rs[i]];
            return cha(mid+1,r,rson[pre],rson[cur],k-ans);
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(ri i=1;i<=n;i++)
          {
              scanf("%d",&val[i]);
              b[i]=val[i];
        }
        int cent=n;
        for(ri i=1;i<=m;i++)
        {
            char opt[5];
            scanf("%s",opt);
            if(opt[0]=='Q')
            {
                scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].k);
                p[i].op=1;
            }
            else
            {
                scanf("%d%d",&p[i].l,&p[i].r);
                b[++cent]=p[i].r;
            }
        }
        sort(b+1,b+cent+1);
        q=unique(b+1,b+cent+1)-b-1;
        build(1,q,root[0]);
        for(ri i=1;i<=n;i++)
        {
            int trmp=lower_bound(b+1,b+1+q,val[i])-b;
            xiu(1,q,root[i-1],root[i],trmp,1);
        }
        for(ri i=1;i<=n;i++)///  L理解 
        {
            T[i]=root[0];
        }
        for(ri i=1;i<=m;i++)
        {
            if(!p[i].op)
            {
                int trmp=lower_bound(b+1,b+q+1,val[p[i].l])-b;
                change(p[i].l,trmp,-1);
                trmp =lower_bound(b+1,b+q+1,p[i].r)-b;
                change(p[i].l,trmp,1);
                val[p[i].l]=p[i].r;
            }
            else
            {
                ls[0]=rs[0]=0;
                for(ri j=p[i].l-1;j>=1;j-=lowbit(j))
                {
                    ls[++ls[0]]=T[j];
                }
                for(ri j=p[i].r;j>=1;j-=lowbit(j))
                {
                    rs[++rs[0]]=T[j];
                }
                int trmp=cha(1,q,root[p[i].l-1],root[p[i].r],p[i].k);
                printf("%d
    ",b[trmp]);
            }
        }
        return 0;
    }
    View Code

      

  • 相关阅读:
    【NOIP2017】蚯蚓
    【CF407B】Long Path
    【NOIP2017】奶酪
    【NOIP2018】赛道修建(正解)
    【NOIP2018】旅行
    【SDOI2010】地精部落
    【NOIP2017】逛公园
    百度云网盘进行注销操作
    百度超级会员租借.我租给你。
    如何在dos中运行java中的jar包
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/11801945.html
Copyright © 2020-2023  润新知