P2617 Dynamic Rankings
题目描述
给定一个含有 \(n\) 个数的序列 \(a_1,a_2 \dots a_n\),需要支持两种操作:
Q l r k
表示查询下标在区间 \([l,r]\) 中的第 \(k\) 小的数C x y
表示将 \(a_x\) 改为 \(y\)
【数据范围】
对于 \(100\%\) 的数据,\(1\le n,m \le 10^5\),\(1 \le l \le r \le n\),\(1 \le k \le r-l+1\),\(1\le x \le n\),\(0 \le a_i,y \le 10^9\)。
Solution:
生套生 模板题,用树状数组维护主席树的前缀和。
首先我们都知道主席树的本质其实是前缀和,如果我们要修改一个点的点权,那么就会牵扯到至多 \(O(n)\) 颗树(它的后继)。这样我们就会十分难受,怎么办呢?
还记得当年在学前缀和时老师同时教了另一个东西: 树状数组。我们在建树时,可以不按照线性前缀和,而在树状数组上建树,这样我们在单点修改时只用修改 \(log_{2}n\) 个点就好了,这样的时间复杂度就是
#include<bits/stdc++.h>
const int N=1e5+5;
const int inf=1e9;
using namespace std;
inline int lowbit(int x){return x&-x;}
int n,m;
int a[N];
struct Segment_Tree{
struct Tree{
int ls,rs,cnt;
}t[N*400];
int cnt,rt[N];
void insert(int &x,int l,int r,int pos,int k)
{
t[x=(x ? x : ++cnt)].cnt+=k;
if(l==r)return ;
int mid=l+r>>1;
if(pos<=mid)insert(t[x].ls,l,mid,pos,k);
if(mid<pos) insert(t[x].rs,mid+1,r,pos,k);
}
void update(int x,int val,int k)
{
for(int u=x;u<=n;u+=lowbit(u))insert(rt[u],0,inf,val,k);
}
int A[N],B[N];
int query(int x,int y,int k)
{
A[0]=B[0]=0;
for(int u=x-1;u;u-=lowbit(u))A[++A[0]]=rt[u];
for(int u=y;u;u-=lowbit(u))B[++B[0]]=rt[u];
int l=0,r=inf,ans=0,mid=0,tmp;
while(l<r)
{
mid=l+r>>1;
tmp=0;
for(int i=1;i<=A[0];i++)tmp-=t[t[A[i]].rs].cnt;
for(int i=1;i<=B[0];i++)tmp+=t[t[B[i]].rs].cnt;
if(tmp>=k)
{
for(int i=1;i<=A[0];i++)A[i]=t[A[i]].rs;
for(int i=1;i<=B[0];i++)B[i]=t[B[i]].rs;
l=ans=mid+1;
}
else
{
for(int i=1;i<=A[0];i++)A[i]=t[A[i]].ls;
for(int i=1;i<=B[0];i++)B[i]=t[B[i]].ls;
r=mid;k-=tmp;
}
}
return ans;
}
}T;
char c[10];
void work()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
T.update(i,a[i],1);
}
for(int i=1,x,y,k;i<=m;i++)
{
scanf("%s",c);
scanf("%d%d",&x,&y);
if(c[0]=='C')
{
T.update(x,a[x],-1);
a[x]=y;
T.update(x,a[x],1);
}
else
{
scanf("%d",&k);
k=y-x+1-k+1;
int ans=T.query(x,y,k);
printf("%d\n",ans);
}
}
}
int main()
{
//freopen("Dynamic Rankings.in","r",stdin);freopen("Dynamic Rankings.out","w",stdout);
work();
return 0;
}
标签:cnt,le,前缀,int,Rankings,Dynamic,P2617
From: https://www.cnblogs.com/LG017/p/18658166