P2617 Dynamic Rankings(整体二分)
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2617 Dynamic Rankings(整体二分)相关的知识,希望对你有一定的参考价值。
题意:
待修改的区间最值问题
题解:
整体二分天然带有修改性
整体二分做不带修改的区间最值—>看这里
现在待修改,我们可以将第l位修改为x,因为我们是用树状数组来维护的,所以把这个过程拆分成将第l个数删去,再将第l个数加上,但是这两个第l数所指的值是不一样的,因为我们是判断,只有值<=mid的数才插入到树状数组中,虽然是同一个位置,但是因为可能改了值导致原本插入,现在不插入,也有可能相反,这样就实现了修改操作,其实还是要把整体二分的原理搞清楚就懂了
比如:当然mid = 3
第L位原本是2现在改成4
一开始第L位是插入到树状数组的(因为2<mid)(读入数据时的操作),然后先将第L位删去(修改操作分离出的删去操作),然后判断现在值是否满足要求,发现不满足(4>mid=3),则不插入到树状数组,这样一套,就完成了修改
代码:
#pragma optimize("Ofast")
#include<bits/stdc++.h>
#define MAXN 300005
#define inf int(1e9)
using namespace std;
typedef long long ll;
int N,M;
int a[MAXN];
struct Node{
int op,x,y,k;//op=insert+1/remove-1,query2
int id;
Node(int op=0, int x=0, int y=0, int k=0, int id=0):op(op), x(x), y(y), k(k), id(id){}
} q[MAXN],lq[MAXN],rq[MAXN];
//
int fw[MAXN];
inline int lbt(int x){
return x&(-x);
}
inline void change(int x, int dv){
for(;x<=N;x+=lbt(x)){
fw[x] += dv;
}
}
inline int query(int x){
int ans = 0;
for(;x>0;x-=lbt(x)){
ans += fw[x];
}
return ans;
}
//
int ANS[MAXN];
void solve(int vl, int vr, int ql, int qr){
//cerr<<"solve: "<<vl<<" "<<vr<<" "<<ql<<" "<<qr<<endl;
if(ql > qr) return;
if(vl == vr){
for(int i=ql;i<=qr;i++){
if(q[i].op==2) ANS[q[i].id] = vl;
}
return;
}
//insert
int mid = (vl + vr)>>1;
int nl = 0, nr = 0;
for(int i=ql;i<=qr;i++){
if(q[i].op != 2){//insert/remove
if(q[i].x <= mid) change(q[i].y, q[i].op), lq[++nl] = q[i];
else rq[++nr] = q[i];
}
else{//query
int n = query(q[i].y) - query(q[i].x-1);
if(q[i].k <= n) lq[++nl] = q[i];
else{
q[i].k -= n;
rq[++nr] = q[i];
}
}
}
//remove
for(int i=ql;i<=qr;i++){
if(q[i].op != 2){
if(q[i].x <= mid) change(q[i].y, -q[i].op);
}
}
for(int i=1;i<=nl;i++) q[ql+i-1] = lq[i];
for(int i=1;i<=nr;i++) q[ql+nl+i-1] = rq[i];
solve(vl, mid, ql, ql+nl-1);
solve(mid+1, vr, ql+nl, qr);
}
int main(){
scanf("%d%d", &N, &M);
int NN = 0, Q = 0;
int x,l,r,k;
for(int i=1;i<=N;++i){
scanf("%d", &a[i]);
q[++NN] = Node(1,a[i],i);
}
char op[5];
for(int i=1;i<=M;i++){
scanf("%s", op);
if(op[0]=='Q'){
scanf("%d%d%d", &l, &r, &k);
q[++NN] = Node(2,l,r,k,++Q);
}
else{
scanf("%d%d", &l, &x);
q[++NN] = Node(-1,a[l],l);
q[++NN] = Node(+1,x,l);
a[l] = x;
}
}
solve(-1e9,1e9,1,NN);
for(int i=1;i<=Q;i++){
printf("%d\\n", ANS[i]);
}
return 0;
}
以上是关于P2617 Dynamic Rankings(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章