http://www.lydsy.com/JudgeOnline/problem.php?id=1901
Orz 主席!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
这主席树理解起来真tm困难,用BIT来套,就不想说什么了
开始想的动态开点,就没有离散化,结果二分的时候可能慢一点
update
今天下午想了一下,发现主席树不难嘛
空间O(nlognlogn)有点吃紧
树状数组每个点维护个前缀,把树状数组询问的点保存起来就可以了
为什么树套树的复杂度多了一个log捏,我今天才知道
可持久化线段树还有一个性质是平衡树不具备的
——每棵树的结构相同,这样就可以整体操作了
//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
/************************************************
Code By willinglive Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/
int n,m;
int a[10010],cnt,b[10010];
int root[10010];
map<int,int>M;
int s[10010];
/
namespace Chair
{///
int sz[4000000],tot;
int ls[4000000],rs[4000000];
void insert(int &o,int L,int R,int x,int val)
{
if(!o) o=++tot;
sz[o]+=val;
if(L==R) return;
int mid=L+R>>1;
if(x<=mid) insert(ls[o],L,mid,x,val);
else insert(rs[o],mid+1,R,x,val);
}
}///
namespace BIT
{///
void add(int o,int x,int val)
{
for(;o<=n;o+=o&-o) Chair::insert(root[o],0,1000000000,x,val);
}
void query(int x,int y,int k)
{
using namespace Chair;
int i,l=0,r=1000000000,mid;
int top=0,topr;
for(i=y;i;i-=i&-i) s[++top]=root[i]; //[1,topr]
topr=top;
for(i=x-1;i;i-=i&-i) s[++top]=root[i]; //[topr+1,top]
while(l<r)
{
mid=l+r>>1;
int res=0;
rep(i,1,topr) res+=sz[ls[s[i]]];
rep(i,topr+1,top) res-=sz[ls[s[i]]];
if(res>=k)
{
r=mid;
rep(i,1,top) s[i]=ls[s[i]];
}
else
{
l=mid+1;
k-=res;
rep(i,1,top) s[i]=rs[s[i]];
}
}
printf("%d\n",l);
}
}///
/
void input()
{
n=read(); m=read();
rep(i,1,n) a[i]=read();
}
void solve()
{
using namespace BIT;
char op[3];int l,r,k;
rep(i,1,n) add(i,a[i],1);
rep(i,1,m)
{
scanf("%s",op); l=read(); r=read();
if(op[0]=='C')
{
add(l,a[l],-1);
add(l,r,1);
a[l]=r;
}
else
{
k=read();
query(l,r,k);
}
}
}
/
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),solve();
return 0;
}