整体二分和线段树分治大部分在线段树上进行处理,可以出去很多重复的计算,对于线段树的每一个区间最多跑一次,没一层是$O(n)$的,最多$log$层所以时间复杂度一般是$O(nlog_n)$
## 整体二分
---
### [METEORS - Meteors](https://www.luogu.com.cn/problem/SP10264)
将修改区间和答案区间二分,将前mid个修改区间和前mid个修改后答案区间里的满足答案的区间拿出来继续查找
```cpp
#include<bits/stdc++.h>
using namespace std;
int a[300005],n,m,k,b[300005],id[300005],head[300005],ecnt,d[300005],ans[300005];
struct Node{
int to,ne;
}e[300005];
void add(int x,int y){
e[++ecnt].ne=head[x],e[ecnt].to=y,head[x]=ecnt;
}
struct node{
int l,r,v;
}c[600005];
struct Tree{
long long tree[300005];
int lowbit(int x){
return x&(-x);
}
void add(int x,int y){
if(x==0) return;
while(x<=m){
tree[x]+=y;
x+=lowbit(x);
}
}
long long query(int x){
long long res=0;
while(x>0){
res+=tree[x];
x-=lowbit(x);
}
return res;
}
}t;
void egg(int l,int r,int x,int y){
if(y<x) return;
// cerr<<l<<' '<<r<<' '<<x<<' '<<y<<'\n';
// for(int i=x;i<=y;i++) cerr<<b[i]<<' ';
// cerr<<'\n';
for(int i=x;i<=y;i++)
if(l==r){
for(int i=x;i<=y;i++) ans[b[i]]=l;
return;
}
int mid=(l+r)>>1;
for(int i=l;i<=mid;i++){
if(c[i].l>c[i].r) t.add(1,c[i].v);
t.add(c[i].l,c[i].v);
t.add(c[i].r+1,-c[i].v);
// cerr<<i<<' '<<c[i].l<<' '<<c[i].r<<' '<<c[i].v<<'\n';
// for(int j=1;j<=m;j++) cerr<<t.query(j)<<'\n';
}
int tot1=x-1,tot2=y+1;
for(int i=x;i<=y;i++){
long long sum=0;
for(int j=head[b[i]];j;j=e[j].ne){
sum+=t.query(e[j].to);
if(sum>=a[b[i]]) break;
}
// cerr<<b[i]<<' '<<sum<<'\n';
&nbs

最低0.47元/天 解锁文章
780

被折叠的 条评论
为什么被折叠?



