第一次外层套权值线段树
每次用splay提取区间然后在线段树上二分即可
一开始想打替罪羊 后来。。差点砸电脑
还是splay好写
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
struct Node
{
Node *lc,*rc,*f;
inline bool l(){return f->lc==this;}
int Con,Rank,Data;
}*empty;
Node A[1000001];
Node*Cache[1200001];
int tot;
inline Node *New_Node()
{
Node *T=Cache[tot--];T->lc=empty,T->rc=empty;T->Con=1,T->Rank=1;
return T;
}
inline void Del(Node*a)
{Cache[++tot]=a;}
inline void Bg()
{
empty=new Node;
empty->lc=empty,empty->rc=empty,
empty->Rank=empty->Data=empty->Con=0;
for(tot=0;tot<=1000000;tot++)Cache[tot]=A+tot;tot--;
}
inline void updata(Node*a){a->Con=(a->Rank=1+a->lc->Con)+a->rc->Con;}
inline void Lc(Node *a)
{
Node*f;
if(a->f->f==a->f)f=a;
else if(a->f->l())a->f->f->lc=a,f=a->f->f;
else a->f->f->rc=a,f=a->f->f;
a->f->lc=a->rc;
a->rc->f=a->f;
a->rc=a->f;
a->f->f=a;
a->f=f;
updata(a->rc),updata(a);
}
inline void Rc(Node *a)
{
Node*f;
if(a->f->f==a->f)f=a;
else if(a->f->l())a->f->f->lc=a,f=a->f->f;
else a->f->f->rc=a,f=a->f->f;
a->f->rc=a->lc;
a->lc->f=a->f;
a->lc=a->f;
a->f->f=a;
a->f=f;
updata(a->lc),updata(a);
}
inline void Change(Node*a){a->l()?Lc(a):Rc(a);}
inline void TwiChange(Node*a){a->l()==a->f->l()?Change(a->f):Change(a->f);Change(a);}
inline void Splay(Node *a)
{
while(a->f->f!=a->f)TwiChange(a);
while(a->f!=a)Change(a);
}
inline void Splay2(Node *a)
{
while(a->f->f->f!=a->f->f)TwiChange(a);
while(a->f->f!=a->f)Change(a);
}
Node *Pre(Node *a,int D)
{
if(a==empty)return a;
if(a->Data>=D)
return Pre(a->lc,D);
Node *R=Pre(a->rc,D);
return R==empty?a:R;
}
Node *Aft(Node *a,int D)
{
if(a==empty)return a;
if(a->Data<=D)
return Aft(a->rc,D);
Node *R=Aft(a->lc,D);
return R==empty?a:R;
}
const
int INF=1<<29;
struct Seg
{
int l,r;
Node* Data;
void Bg(){Node *Bg=New_Node(),*Ed=New_Node();
Bg->Data=-1;Ed->Data=INF;Ed->f=Bg;Bg->rc=Ed;updata(Ed);updata(Bg);Bg->f=Bg;Data=Bg;}
}T[100001];
void Build(int place,int l,int r)
{
T[place].Bg();
T[place].l=l;
T[place].r=r;
if(l^r)
{
Build(place<<1|1,(l+r>>1)+1,r),
Build(place<<1,l,l+r>>1);
}
return ;
}
int Query(int place,int l,int r)
{
Node *B,*E;
B=Pre(T[place].Data,l);
E=Aft(T[place].Data,r);
Splay(T[place].Data=B);
Splay2(E);
return E->Rank-1;
}
void Del(int place,int l)
{
Node *B,*E;
B=Pre(T[place].Data,l);
E=Aft(T[place].Data,l);
Splay(B);
Splay2(E);
if(E->lc!=empty)
Del(E->lc);
E->lc=empty;
Splay(T[place].Data=E);
}
void Add(int place,int l)
{
Node*N;
Node *B,*E;
B=Pre(T[place].Data,l);
E=Aft(T[place].Data,l);
Splay(B);
Splay2(E);
N=New_Node();
N->Data=l;
E->lc=N;
N->f=E;
updata(N);
Splay(T[place].Data=N);
}
int Query(int place,int l,int r,int k)
{
if(T[place].l^T[place].r)
{
int L=Query(place<<1,l,r);
if(L>=k)return Query(place<<1,l,r,k);
return Query(place<<1|1,l,r,k-L);
}
else
return T[place].l;
}
void Del(int place,int l,int data)
{
Del(place,l);
if(T[place].l^T[place].r)
{
if(T[place<<1|1].l<=data)Del(place<<1|1,l,data);
else Del(place<<1,l,data);
}
return ;
}
void Add(int place,int l,int data)
{
Add(place,l);
if(T[place].l^T[place].r)
{
if(T[place<<1|1].l<=data)Add(place<<1|1,l,data);
else Add(place<<1,l,data);
}
return ;
}
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Que
{
bool q;
int l,r,k;
void In(){do c=getchar();while(c!='Q'&&c!='C');q=c=='Q';read(l),read(r);if(q)read(k);}
}L[11001];
int n,M;
map<int,int>Q;
int TT[110001];
int Data[11001];
int main()
{
read(n),read(M);
int m=-1;
for(int i=1;i<=n;i++)
read(TT[i]),m=max(m,Data[i]=TT[i]);
for(int i=1;i<=M;i++)
{
L[i].In();
if(L[i].q)TT[i+n]=m;
else m=max(TT[i+n]=L[i].r,m);
}
int T=n+M;
Bg();
sort(TT+1,TT+1+T);
T=unique(TT+1,TT+1+T)-TT-1;
for(int i=1;i<=T;i++)
Q[TT[i]]=i;
Build(1,1,m=Q[m]);
for(int i=1;i<=n;i++)
Data[i]=Q[Data[i]],Add(1,i,Data[i]);
int ans;
for(int i=1;i<=M;i++)
if(!L[i].q)L[i].r=Q[L[i].r];
for(int i=1;i<=M;i++)
{
if(L[i].q)
{
ans=Query(1,L[i].l,L[i].r,L[i].k);
ans=TT[ans];
printf("%d\n",ans);
}
else
Del(1,L[i].l,Data[L[i].l]),Add(1,L[i].l,L[i].r),Data[L[i].l]=L[i].r;
}
return 0;
}