#include<cstdio>#include<algorithm>usingnamespace std;
#define MAXN 100000structelement {//修改int loc;
int time;//时间戳int value;
int com;
element (){}
element (int loc1, int time1, int value1, int com1) {
loc = loc1;
time = time1;
value = value1;
com = com1;
}
}se[MAXN * 3 + 5], teme[MAXN * 3 + 5];
int End = 0;
structquestion {//询问int num;
int l, r;
int k;
int time;//时间戳question (){}
question (int num1, int l1, int r1, int k1, int time1) {
num = num1;
l = l1;
r = r1;
k = k1;
time = time1;
}
}sq[MAXN + 5], temq[MAXN + 5];
int num = 0;
bool vis[MAXN + 5];
int BIT[MAXN + 5];//单点修改, 区间查询通过BIT来实现int snow[MAXN + 5];//每次修改需要先删除这个位置上一次的值, 再添加新的值, 所以用一个数组存int answer[MAXN + 5];//答案intlowbit(int i){
return i & (-i);
}
voidchange(int l, int v){
for (int i = l; i <= MAXN; i += lowbit (i)) {
BIT[i] += v;
}
}
intSum(int l){
int ans = 0;
for (int i = l; i; i ^= lowbit (i)) {
ans += BIT[i];
}
return ans;
}
intask(int l, int r){
returnSum (r) - Sum (l - 1);
}
voiddichotomy(int le, int re, int lq, int rq, int vl, int vr){
if (vl == vr) {//如果二分到底了, 就直接是答案了for (int i = lq; i <= rq; i ++) {
answer[sq[i].num] = vl;
}
return ;
}
int mid = (vl + vr) >> 1;
int ie = le, iq = lq;
for (int i = lq; i <= rq; i ++) {//相当于普通二分中check的0, 1 vis[i] = 0;
}
while (ie <= re && iq <= rq) {
if (se[ie].time <= sq[iq].time) {//时间戳来判断操作先后change (se[ie].loc, (se[ie].value <= mid) * se[ie].com);
ie ++;
}
else {
int sum = ask (sq[iq].l, sq[iq].r);
vis[iq] = (sum >= sq[iq].k);
if (!vis[iq]) {
sq[iq].k -= sum;//分到mid右边后要将左边修改的贡献提前算上好 }
iq ++;
}
}
while (iq <= rq) {
int sum = ask (sq[iq].l, sq[iq].r);
vis[iq] = (sum >= sq[iq].k);
if (!vis[iq]) {
sq[iq].k -= sum;
}
iq ++;
}
for (int i = le; i < ie; i ++) {//将BIT清0change (se[i].loc, -(se[i].value <= mid) * se[i].com);
}
//将询问和修改都按照mid分为左右两边int ne = le - 1;
for (int i = le; i <= re; i ++) {
if (se[i].value <= mid) {
teme[++ ne] = se[i];
}
}
for (int i = le, j = ne; i <= re; i ++) {
if (se[i].value > mid) {
teme[++ j] = se[i];
}
}
for (int i = le; i <= re; i ++) {
se[i] = teme[i];
}
int nq = lq - 1;
for (int i = lq; i <= rq; i ++) {
if (vis[i]) {
temq[++ nq] = sq[i];
}
}
for (int i = lq, j = nq; i <= rq; i ++) {
if (!vis[i]) {
temq[++ j] = sq[i];
}
}
for (int i = lq; i <= rq; i ++) {
sq[i] = temq[i];
}
if (nq >= lq) {
dichotomy (le, ne, lq, nq, vl, mid);
}
if (nq < rq) {
dichotomy (ne + 1, re, nq + 1, rq, mid + 1, vr);
}
}
intmain(){
int n, m;
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; i ++) {
scanf ("%d", &snow[i]);
se[++End] = element (i, 0, snow[i], 1);
}
for (int i = 1; i <= m; i ++) {
char opt = getchar ();
while (opt > 'Z' || opt < 'A') {
opt = getchar ();
}
if (opt == 'Q') {
int l, r, k;
scanf ("%d %d %d", &l, &r, &k);
++num;
sq[num] = question (num, l, r, k, i);
}
elseif (opt == 'C') {
int l;
int v;
scanf ("%d %d", &l, &v);
se[++End] = element (l, i, snow[l], -1);
snow[l] = v;
se[++End] = element (l, i, snow[l], 1);
}
};
dichotomy (1, End, 1, num, 0, 1e9);
for (int i = 1; i <= num; i ++) {
printf ("%d\n", answer[i]);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!