整体二分

只适用于存在加减性的问题

有时候可以把一维主席树变成线段树+整体二分降低难度

一直没写过

今天写了一下

要注意的是

二分有负数的时候

加一句特判

int mid=(h1+t1)/2;
if (h1<=0&&t1<=0) mid=(h1+t1-1)/2;

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IL inline
#define rint register int
#define me(x) memset(x,0,sizeof(x))
#define fi first
#define se second
//#define mid ((h+t)>>1)
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define setit set<int>::iterator
char ss[1<<24],*A=ss,*B=ss;
IL char gc()
{
  return (A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++);
}
template<class T>void read(T &x)
{
  rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=c^48;
  while (c=gc(),47<c&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
}
char sr[1<<24],z[20]; int C=-1,Z;
template <class T> void wer(T x)
{
  if (x<0) sr[++C]='-',x=-x;
  while (z[++Z]=x%10+48,x/=10);
  while (sr[++C]=z[Z],--Z); sr[++C]='
';
}
template<class T>IL T MAX(T x,T y)
{
  if (x>y) return(x); else return(y);
}
template<class T>IL T MIN(T x,T y)
{
  if (x<y) return(x); else return(y);
}
template<class T>IL void SWAP(T &x,T &y)
{
  T tmp=x; x=y; y=tmp;
}
IL setit prev(register setit it)
{
  register setit it2=it;
  return(--it2);
}
IL setit next(register setit it)
{
  register setit it2=it;
  return(++it2);
}
const int N=3e5;
const int INF=1.1e9;
struct re{
  int a,b,c,d;
}b[N];
int f[N],a[N],ans[N],n,m;
#define lowbit(x) (x&(-x))
IL void add(int x,int y)
{
  while (x<=n)
  {
    f[x]++;
    x+=lowbit(x);
  }
}
IL int query(int x)
{
  int ans=0;
  while (x>0)
  {
    ans+=f[x];
    x-=lowbit(x);
  }
  return(ans);
}
void find(int h,int t,int h1,int t1)
{
 // cout<<h1<<" "<<t1<<endl;
  if (h>t) return;
  if (h1==t1)
  {
    rep(i,h,t) ans[b[i].d]=h1;
    return;
  }
  memset(f,0,sizeof(f));
  int mid=(h1+t1)/2;
  if (h1<=0&&t1<=0) mid=(h1+t1-1)/2;
  rep(i,1,n) if (a[i]<=mid&&a[i]>=h1) add(i,1);
  queue<re> q1,q2;
  rep(i,h,t)
  {
    int ans=query(b[i].b)-query(b[i].a-1);
    if (ans>=b[i].c) q1.push((re){b[i].a,b[i].b,b[i].c,b[i].d});
    else q2.push((re){b[i].a,b[i].b,b[i].c-ans,b[i].d});
  }
  int cnt=h-1;
  while (!q1.empty())
  {
    re x=q1.front(); q1.pop();
    b[++cnt]=x;
  }
  find(h,cnt,h1,mid);
  int cnt2=cnt;
  while (!q2.empty())
  {
    re x=q2.front(); q2.pop();
    b[++cnt]=x;
  }
  find(cnt2+1,t,mid+1,t1);
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  read(n); read(m);
  rep(i,1,n) read(a[i]);
  rep(i,1,m)
  {
    read(b[i].a); read(b[i].b); read(b[i].c); b[i].d=i; 
  }
  find(1,m,-INF,INF);
  rep(i,1,m) wer(ans[i]);
  fwrite(sr,1,C+1,stdout);
  return 0;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/9180865.html