http://www.elijahqi.win/archives/3059
Description
给出N个平面上的点。保证每一个点的坐标都是正奇数。
你要在平面上画两条线,一条是x=a,一条是y=b,且a和b都是偶数。
直线将平面划成4个部分,要求包含点数最多的那个部分点数最少。
Input
第一行一个数N。
接下来N行每行描述一个点
N<=100000
1<=x,y<=1000000
Output
输出一个数表示最少的点数。
Sample Input
7
7 3
5 5
7 13
3 1
11 7
5 3
9 1
Sample Output
2
HINT
Source
枚举横坐标 然后上下维护线段树 然后每次做的时候对于纵坐标二分一个位置
max(l1,l2)>=max(r1,r2) 然后取一下四个中的最大值返回即可 因为前面这个函数是单峰函数所以可以在线段树上直接二分即可
#include<cstdio>
#include<cctype>
#include<algorithm>
#define lc (x<<1)
#define rc (x<<1|1)
#define inf 0x3f3f3f3f
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int N=100010;
struct P{
int x,y;
}point[N];
struct node{int v[2];}tree[N<<3];
int d[N],nn,d1[N],n1;
inline bool cmp(const P &a,const P &b){return a.x<b.x;}
inline void insert1(int x,int l,int r,int p,int v,int op){
tree[x].v[op]+=v;if (l==r) return;int mid=l+r>>1;
if(p<=mid) insert1(lc,l,mid,p,v,op);
else insert1(rc,mid+1,r,p,v,op);
}
inline int query(int x,int l,int r,int l1,int r1,int l2,int r2){
int mid=l+r>>1;
int lv0=tree[lc].v[0],rv0=tree[rc].v[0];
int lv1=tree[lc].v[1],rv1=tree[rc].v[1];
if (l==r) {
lv0=tree[x].v[0],rv0=tree[x].v[0];
lv1=tree[x].v[1],rv1=tree[x].v[1];
if (max(l1+lv0,l2+lv1)>=max(r1+rv0,r2+rv1))
r1+=rv0,r2+=rv1;else l1+=lv0,l2+=lv1;
return max(max(l1,l2),max(r1,r2));
}
if (max(lv0+l1,lv1+l2)>=max(rv0+r1,rv1+r2))
return query(lc,l,mid,l1,rv0+r1,l2,rv1+r2);
else return query(rc,mid+1,r,l1+lv0,r1,l2+lv1,r2);
}
int main(){
freopen("bzoj4411.in","r",stdin);
int n=read();
for (int i=1;i<=n;++i) point[i].x=read(),point[i].y=read(),d[++nn]=point[i].y,
d1[++n1]=point[i].x;sort(d1+1,d1+n1+1);n1=unique(d1+1,d1+n1+1)-d1-1;
sort(d+1,d+nn+1);nn=unique(d+1,d+nn+1)-d-1;
for (int i=1;i<=n;++i){
point[i].x=lower_bound(d1+1,d1+n1+1,point[i].x)-d1;
point[i].y=lower_bound(d+1,d+nn+1,point[i].y)-d;
}
sort(point+1,point+n+1,cmp);int now=1,ans=inf;
//for (int i=1;i<=n;++i) printf("%d %d\n",point[i].x,point[i].y);
for (int i=1;i<=n;++i) insert1(1,1,nn,point[i].y,1,1);
for (int i=1;i<=n1;++i){
while(point[now].x==i) insert1(1,1,nn,point[now].y,-1,1),insert1(1,1,nn,point[now].y,1,0),++now;
ans=min(ans,query(1,1,nn,0,0,0,0));
}printf("%d\n",ans);
return 0;
}