ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【洛谷P2617】Dynamic Rankings

2019-03-02 21:53:10  阅读:256  来源: 互联网

标签:ch 洛谷 树状 int Dynamic P2617 小值 maxn 维护


题目大意:维护带修改区间 K 小值。

题解:学习到了树状数组套主席树。
主席树,即:可持久化权值线段树,支持维护静态区间的 K 小值问题,其核心思想是维护 N 棵权值线段树,每个线段树维护的是序列 [1,i] 的权值,并根据可持久化思想使得空间复杂度维持在 \(O(nlogn)\)。
树状数组套主席树,即:带修主席树,支持维护带修改区间 K 小值的问题,其核心思想是改变静态主席树的前缀和处理方式,在这里采用树状数组中的前缀和处理方式,平衡了修改和查询的时间和空间。时间和空间复杂度为 \(O(nlognlogn)\)。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

inline int read(){
    int x=0,f=1;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    return f*x;
}

char opt[5];
int n,m,a[maxn],tmp[2][20],cnt[2];
int d[maxn<<1],len;
struct operation{bool tag;int l,r,k;int pos,val;}q[maxn];
struct node{
    #define ls(x) t[x].lc
    #define rs(x) t[x].rc
    int lc,rc,sum;
}t[maxn*300];
int tot,root[maxn];
inline void pushup(int o){t[o].sum=t[ls(o)].sum+t[rs(o)].sum;}
void insert(int &o,int l,int r,int pos,int val){
    if(!o)o=++tot;
    if(l==r){t[o].sum+=val;return;}
    int mid=l+r>>1;
    if(pos<=mid)insert(ls(o),l,mid,pos,val);
    else insert(rs(o),mid+1,r,pos,val);
    pushup(o);
}
int query(int l,int r,int k){
    if(l==r)return l;
    int mid=l+r>>1;
    int lsize=0;
    for(int i=1;i<=cnt[1];i++)lsize+=t[ls(tmp[1][i])].sum;
    for(int i=1;i<=cnt[0];i++)lsize-=t[ls(tmp[0][i])].sum;
    if(k<=lsize){
        for(int i=1;i<=cnt[1];i++)tmp[1][i]=ls(tmp[1][i]);
        for(int i=1;i<=cnt[0];i++)tmp[0][i]=ls(tmp[0][i]);
        return query(l,mid,k);
    }else{
        for(int i=1;i<=cnt[1];i++)tmp[1][i]=rs(tmp[1][i]);
        for(int i=1;i<=cnt[0];i++)tmp[0][i]=rs(tmp[0][i]);
        return query(mid+1,r,k-lsize);
    }
}
inline int lowbit(int x){return x&-x;}
inline void add(int x,int val){
    int pos=lower_bound(d+1,d+len+1,a[x])-d;
    for(int i=x;i<=n;i+=lowbit(i))insert(root[i],1,len,pos,val);
}
int querykth(int l,int r,int k){
    memset(tmp,0,sizeof(tmp)),cnt[1]=cnt[0]=0;
    for(int i=r;i;i-=lowbit(i))tmp[1][++cnt[1]]=root[i];
    for(int i=l-1;i;i-=lowbit(i))tmp[0][++cnt[0]]=root[i];
    return query(1,len,k);
}

void read_and_parse(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)d[++len]=a[i]=read();
    for(int i=1;i<=m;i++){
        scanf("%s",opt);
        if(opt[0]=='Q')q[i].tag=0,q[i].l=read(),q[i].r=read(),q[i].k=read();
        else q[i].tag=1,q[i].pos=read(),d[++len]=q[i].val=read();
    }
    sort(d+1,d+len+1);
    len=unique(d+1,d+len+1)-d-1;
    for(int i=1;i<=n;i++)add(i,1);
}

void solve(){
    for(int i=1;i<=m;i++){
        if(q[i].tag){
            add(q[i].pos,-1);
            a[q[i].pos]=q[i].val;
            add(q[i].pos,1);
        }else{
            printf("%d\n",d[querykth(q[i].l,q[i].r,q[i].k)]);
        }
    }
}

int main(){
    read_and_parse();
    solve();
    return 0;
}

标签:ch,洛谷,树状,int,Dynamic,P2617,小值,maxn,维护
来源: https://www.cnblogs.com/wzj-xhjbk/p/10463097.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有