给大家一波福利,我在洛谷上放了一道bzoj权限题
传送门
都不要说,要不我会被打。。。
有人说的话,我就删了这题了。。
然后就是这个题就是个模板题,直接板子。
我的封装过了,看一看细节,直接用就好了。
代码:
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=1e4+5;
const int M=N*300;
struct node{
int ls,rs,size;
}t[M];
int n,m,cnt,tot;
int a[N],b[N<<1];
inline int Hash(int x){
return lower_bound(b+1,b+cnt+1,x)-b;
}
struct Q{
int opt,A,B,K;
}q[N];
struct bit_seg{
int add[30],mns[30],cnt1,cnt2;
int root[N];
inline int lowbit(int x){
return x&-x;
}
inline void insert(int num,int &now,int l,int r,int val){
t[++tot]=t[now];
now=tot;
t[now].size+=val;
if(l==r)return;
int mid=(l+r)>>1;
if(num<=mid)insert(num,t[now].ls,l,mid,val);
else insert(num,t[now].rs,mid+1,r,val);
}
inline int query(int l,int r,int k){
if(l==r)return b[l];
int lsize=0;
for(int i=1;i<=cnt1;i++)lsize+=t[t[add[i]].ls].size;
for(int i=1;i<=cnt2;i++)lsize-=t[t[mns[i]].ls].size;
int mid=(l+r)>>1;
if(k<=lsize){
for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].ls;
for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].ls;
return query(l,mid,k);
}
else{
for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].rs;
for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].rs;
return query(mid+1,r,k-lsize);
}
}
inline void build(){
for(int i=1;i<=n;i++){
a[i]=Hash(a[i]);
for(int j=i;j<=n;j+=lowbit(j)){
insert(a[i],root[j],1,cnt,1);
}
}
}
inline int Query(int l,int r,int k){
cnt1=cnt2=0;
for(int i=l-1;i;i-=lowbit(i))mns[++cnt2]=root[i];
for(int i=r;i;i-=lowbit(i))add[++cnt1]=root[i];
return query(1,cnt,k);
}
inline void Insert(int pos,int x){
for(int i=pos;i<=n;i+=lowbit(i)){
insert(a[pos],root[i],1,cnt,-1);
}
a[pos]=Hash(x);
for(int i=pos;i<=n;i+=lowbit(i)){
insert(a[pos],root[i],1,cnt,1);
}
}
}tree;
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();b[++cnt]=a[i];
}
for(int i=1;i<=m;i++){
char ch[3];
scanf("%s",ch);
if(ch[0]=='Q'){
q[i].opt=0;q[i].A=read();q[i].B=read();q[i].K=read();
}
else{
q[i].opt=1;q[i].A=read();q[i].B=read();b[++cnt]=q[i].B;
}
}
sort(b+1,b+cnt+1);
cnt=unique(b+1,b+cnt+1)-b-1;
tree.build();
for(int i=1;i<=m;i++){
if(q[i].opt){
tree.Insert(q[i].A,q[i].B);
}
else{
printf("%d\n",tree.Query(q[i].A,q[i].B,q[i].K));
}
}
return 0;
}