题意:动态区间第k大
题解:带修改主席树或者整体二分。
带修改主席树
普通的主席树是通过让rt[i]重用前一棵树rt[i-1]来降低若干个权值线段树复杂度的数据结构,带修改的主席树是通过rt[i]重用上一个版本的rt[i]来降低若干个权值线段树复杂度的数据结构。普通的主席树通过重用前一棵树来直接朴素地计算前缀和,带修改的主席树通过重用上一版本的自己来更新当前点,所以不再是通过继承前一棵树的前缀和来维护当前树的前缀和,待修改主席树把树根rt当成一个个点,通过树状数组维护单点修改,区间查询前缀和
具体实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
const int maxn=1e6+5;
int tot,rt[maxn],siz[maxn*64],a[maxn],b[maxn],L[maxn],R[maxn],t1,t2;
struct node{
int lson;
int rson;
}no[maxn*64];
struct que{
int type;
int l;
int r;
int k;
}q[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int &Rt,int oldrt,int l,int r,int pos,int v){
Rt=++tot;
no[Rt]=no[oldrt];
siz[Rt]=siz[oldrt]+v;
if(l==r){
return;
}
int mid=(l+r)>>1;
if(mid>=pos)update(no[Rt].lson,no[oldrt].lson,l,mid,pos,v);
else update(no[Rt].rson,no[oldrt