整体二分乱扯
前言
- msjing现在好饿啊啊啊啊啊
整体二分
- 这个东东是怎么来的捏
- 由于一些题目经常把询问每个都二分卡爆,所以可以依据询问的关联性直接将多个二分合并为一个
- 很吊对不对,
但是msjing真的很饿 - 这个东西是离线的哦
操作与使用
- 整体二分一般是多个询问并行的查询方法,结合例题看看
例题P3834 【模板】可持久化线段树 2
欸,我们直接用主席树创过去- 我们考虑朴素做法
- 常规来说单查区间第 \(k\) 大二分就可以,但是现在是多次询问,复杂度飞起来
- 所以我们采用整体二分
- 那么我们就找到了整体二分的使用条件
1.询问可二分
2.修改之间互不影响
3.离线
- 说白了就是可以单个二分且每次二分互不影响就可以整体
- 那我们说一下怎么做
- 把操作(这题没操作,但是后面都这么说)和区间全读进去
- 开始二分,对于操作,判位置与 \(mid\) 关系,小于等于向左,大于向右
- 对于查询,也与 \(mid\) 比较,此时需要转化,对于所查区间,若这个区间内的数大于等于 \(k\),证明左区间够用,向左,否则向右,区间个数可以用 \(BIT\) 维护
- 当到达叶子节点时,直接把 \(l\) 加入答案(因为二分的是答案)
- 就没了
- 实现的话由于讲课的博客写的是
vector,但msjing是个毒瘤用的是数组,e,其实是贺的
点击查看代码
#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=5e5+10,inf=0x7f7f7f7f;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,a[maxn],ans[maxn];
int tot;
struct __ {int x,y,k,id,op;}q[maxn],q1[maxn],q2[maxn];
struct BIT
{
int c[maxn];
int lb(int x) {return x&(-x);}
void add(int x,int v) {while (x<=n) c[x]+=v,x+=lb(x);}
int que(int x)
{
int res=0;
while (x)
{
res+=c[x];
x-=lb(x);
}
return res;
}
}BT;
void sol(int L,int R,int l,int r)
{
if (L>R) return;
if (l == r)
{
for (int i=L;i<=R;i++) if (q[i].op == 2) ans[q[i].id]=l;
return;
}
int mid=(l+r) >> 1;
int t1=0,t2=0;
for (int i=L;i<=R;i++)
{
if (q[i].op == 1)
{
if (q[i].x<=mid) BT.add(q[i].id,1),q1[++t1]=q[i];
else q2[++t2]=q[i];
}
else
{
int res=BT.que(q[i].y)-BT.que(q[i].x-1);
if (res>=q[i].k) q1[++t1]=q[i];
else q[i].k-=res,q2[++t2]=q[i];
}
}
for (int i=1;i<=t1;i++) if (q1[i].op == 1) BT.add(q1[i].id,-1);
for (int i=1;i<=t1;i++) q[i+L-1]=q1[i];
for (int i=1;i<=t2;i++) q[i+L+t1-1]=q2[i];
sol(L,L+t1-1,l,mid),sol(L+t1,R,mid+1,r);
}
int main()
{
n=read(),m=read();
for (int i=1;i<=n;i++)
{
int x=read();
q[++tot]={x,1,(int)1e9,i,1};
}
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),k=read();
q[++tot]={x,y,k,i,2};
}
sol(1,tot,(int)-1e9,(int)1e9);
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
- 但是msjing真的好饿啊啊啊啊啊
进阶
- msjing改红温了,全咕🤣

后话
- e,这个坑就撂这先不填了,什么时候有精力了再说
- 晶石候任:一定要学
vector做法不然会非常红

浙公网安备 33010602011771号