P2617 Dynamic Rankings(动态区间第k小)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2617 Dynamic Rankings(动态区间第k小)相关的知识,希望对你有一定的参考价值。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
#define mid (l+r>>1)
int n,m,li[maxn<<2],top,a[maxn];
struct p
{
int type,l,r,k;
}q[maxn];
int sum[maxn<<9],ls[maxn<<9],rs[maxn<<9],id;
int rt1[maxn<<9],rt2[maxn<<9],rt[maxn];
inline int lowbit(int x){ return x&(-x); }
void update_sgT(int &rt,int l,int r,int val,int zhi)
{
if( !rt ) rt = ++id;
if( l==r ){ sum[rt] += zhi; return; }
if( val<=mid ) update_sgT( ls[rt],l,mid,val,zhi );
else update_sgT( rs[rt],mid+1,r,val,zhi );
sum[rt] = sum[ls[rt]]+sum[rs[rt]];
}
void update_BIT(int x,int val,int zhi)
{
//把x位置权值线段树上的val位置修改zhi
for(;x<=n;x+=lowbit(x) ) update_sgT( rt[x],1,top,val,zhi );
}
void get_root(int l,int r)//获得[l,r]的节点组成前缀树
{
rt1[0] = rt2[0] = 0;
for(int i=l-1;i;i-=lowbit(i) ) rt1[++rt1[0]] = rt[i];//返回线段树的根节点
for(int i=r;i;i-=lowbit(i) ) rt2[++rt2[0]] = rt[i];
}
int ask(int l,int r,int k)
{
// cout << l << " " << r << endl;
if( l==r ) return l;
int x = 0;
for(int i=1;i<=rt1[0];i++) x -= sum[ls[rt1[i]]];
for(int i=1;i<=rt2[0];i++) x += sum[ls[rt2[i]]];
if( k<=x )
{
for(int i=1;i<=rt1[0];i++) rt1[i] = ls[rt1[i]];
for(int i=1;i<=rt2[0];i++) rt2[i] = ls[rt2[i]];
return ask(l,mid,k );
}
else
{
for(int i=1;i<=rt1[0];i++) rt1[i] = rs[rt1[i]];
for(int i=1;i<=rt2[0];i++) rt2[i] = rs[rt2[i]];
return ask(mid+1,r,k-x );
}
}
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++) scanf("%d",&a[i] );
for(int i=1;i<=n;i++) li[++top] = a[i];
for(int i=1;i<=m;i++)
{
string w; cin >> w;
if( w=="Q" )
{
q[i].type = 0;
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
}
else
{
q[i].type = 1;
scanf("%d%d",&q[i].l,&q[i].k);
li[++top] = q[i].k;
}
}
sort( li+1,li+1+top );
top = unique(li+1,li+1+top )-li-1;
for(int i=1;i<=n;i++)
a[i] = lower_bound( li+1,li+1+top,a[i] )-li;
for(int i=1;i<=m;i++)
if( q[i].type ) q[i].k= lower_bound( li+1,li+1+top,q[i].k )-li;
for(int i=1;i<=n;i++) update_BIT( i,a[i],1 );
for(int i=1;i<=m;i++)
{
if( q[i].type )
{
update_BIT( q[i].l,a[q[i].l],-1 );
a[q[i].l] = q[i].k;
update_BIT( q[i].l,q[i].k,1 );
}
else
{
get_root( q[i].l,q[i].r );//取出[1,l-1]和[1,r]的前缀树节点
printf("%d\\n",li[ask(1,top,q[i].k)] );
}
}
}
以上是关于P2617 Dynamic Rankings(动态区间第k小)的主要内容,如果未能解决你的问题,请参考以下文章
ybt金牌导航4-6-6luogu P2617动态排名 / Dynamic Rankings
P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)