1 /**************************************************************
2 Problem: 1901
3 User: TCtower
4 Language: C++
5 Result: Accepted
6 Time:612 ms
7 Memory:24988 kb
8 ****************************************************************/
9
10 #include <iostream>
11 #include <cstring>
12 #include <cstdio>
13 #include <cmath>
14 #include <cstring>
15 #include <algorithm>
16 #include <vector>
17 //#define LOCAL
18 const int maxn=10000+5;
19 const int INF=99999999;
20 const int maxnode=2000000+10;
21 using namespace std;
22 struct OP
23 {
24 int type;//0代表询问,1代表改变
25 int l,r,k;
26 }op[maxn];
27 //点结构体
28 struct node
29 {
30 int ls,rs,w;
31 node(){ls=rs=w=0;}
32 }T[maxnode];
33 vector<int>LX;
34 vector<int>Q1,Q2;
35 int a[maxn],n,q,n1;
36 int cnt,root[maxn*2];
37
38 void init();
39 void work();
40 //树状数组用
41 inline int lowbit(int i){return i&-i;}
42 inline int find(int i)
43 {
44 //二分查找不解释
45 return (lower_bound(LX.begin(),LX.begin()+n1,i)-LX.begin())+1;
46 }
47 void build(int &i,int l,int r,int val);
48 void query(int l,int r,int k);//区间第k大
49 //其实我觉得不传副本速度会上升?
50 int Qy(vector<int>Q1,vector<int>Q2,int l,int r,int k);
51 void my_ins(int pos,int x,int v);
52 void ins(int &i,int l,int r,int x,int v);
53
54 int main()
55 {
56 #ifdef LOCAL
57 freopen("data.txt","r",stdin);
58 freopen("out.txt","w",stdout);
59 #endif
60 init();//读入与初始化
61 work();
62 return 0;
63 }
64 void init()
65 {
66 scanf("%d%d",&n,&q);
67 LX.clear();
68 for (int i=1;i<=n;i++)
69 {
70 scanf("%d",&a[i]);
71 LX.push_back(a[i]);
72 }
73 char str[10];
74 for (int i=1;i<=q;i++)
75 {
76 scanf("%s",str);
77 if (str[0]=='Q')
78 {
79 op[i].type=0;
80 scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k);
81 }
82 else
83 {
84 op[i].type=1;
85 scanf("%d%d",&op[i].l,&op[i].r);
86 LX.push_back(op[i].r);
87 }
88 }
89 sort(LX.begin(),LX.end());
90 n1=unique(LX.begin(),LX.end())-LX.begin();
91 }
92 void ins(int &i,int l,int r,int x,int v)
93 {
94 if (i==0) {T[++cnt]=T[i];i=cnt;}//没有创建过新的节点
95 T[i].w+=v;
96 if (l==r) return;
97 int mid=(l+r)>>1;
98 if (x<=mid) ins(T[i].ls,l,mid,x,v);
99 else ins(T[i].rs,mid+1,r,x,v);
100 }
101 void my_ins(int pos,int x,int v)
102 {
103 int t=find(x);//找到x的位置
104 for (int i=pos;i<=n;i+=lowbit(i))
105 {
106 ins(root[i],1,n1,t,v);
107 }
108 }
109 int Qy(vector<int>Q1,vector<int>Q2,int l,int r,int k)
110 {
111 if (l==r) return l;
112 int c=0,mid=(l+r)>>1;
113 //这两句可以互换,统计总数
114 for (int i=0;i<Q1.size();i++) c-=T[T[Q1[i]].ls].w;
115 for (int i=0;i<Q2.size();i++) c+=T[T[Q2[i]].ls].w;
116 //大于k说明在左子树中而不右子树
117 for (int i=0;i<Q1.size();i++) Q1[i]=(c>=k?T[Q1[i]].ls:T[Q1[i]].rs);
118 for (int i=0;i<Q2.size();i++) Q2[i]=(c>=k?T[Q2[i]].ls:T[Q2[i]].rs);
119 if (c>=k) return Qy(Q1,Q2,l,mid,k);//继续向下寻找
120 else return Qy(Q1,Q2,mid+1,r,k-c);
121 }
122 void query(int l,int r,int k)
123 {
124 Q1.clear();Q2.clear();//临时队列清空
125 Q1.push_back(root[l!=1?l-1+n:0]);
126 Q2.push_back(root[r+n]);
127 for (int i=l-1;i;i-=lowbit(i)) Q1.push_back(root[i]);
128 for (int i=r;i;i-=lowbit(i)) Q2.push_back(root[i]);
129 int t=Qy(Q1,Q2,1,n1,k);
130 printf("%d\n",LX[t-1]);
131 }
132 void work()
133 {
134 cnt=0;
135 memset(root,0,sizeof(root));
136 for (int i=1;i<=n;i++)
137 {
138 root[i+n]=root[i+n-1];
139 int t=find(a[i]);
140 build(root[i+n],1,n1,t);
141 }
142 for (int i=1;i<=q;i++)
143 {
144 if (op[i].type==0)
145 query(op[i].l,op[i].r,op[i].k);
146 else
147 {
148 my_ins(op[i].l,a[op[i].l],-1);
149 my_ins(op[i].l,op[i].r,1);
150 //修改
151 a[op[i].l]=op[i].r;
152 }
153 }
154 }
155 void build(int &i,int l,int r,int val)
156 {
157 //对于修改过的每一个点
158 //都要新建一个副本
159 T[++cnt]=T[i];i=cnt;
160 T[i].w++;
161 if (l==r) return;
162 int mid=(l+r)>>1;
163 //按值建线段树
164 if (val<=mid) build(T[i].ls,l,mid,val);
165 else build(T[i].rs,mid+1,r,val);
166 }