BZOJ 4411: [Usaco2016 Feb]Load balancing 线段树+二分
code:
#include <bits/stdc++.h> #define N 100060 #define M 1000000 #define lson x<<1 #define rson x<<1|1 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,num[N*10],ans=N,X0,X1; struct node { int x0,x1; }t[N*10*4]; struct Point { int x,y; friend bool operator<(Point a,Point b) { return a.y<b.y; } }a[N]; void pushup(int x) { t[x].x0=t[lson].x0+t[rson].x0; t[x].x1=t[lson].x1+t[rson].x1; } void build(int x,int l,int r) { if(l==r) { t[x].x0=num[l]; t[x].x1=0; return; } int mid=(l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); pushup(x); } void update(int x,int l,int r,int p) { if(l==r) { t[x].x0--,t[x].x1++; return; } int mid=(l+r)>>1; if(p<=mid) update(lson,l,mid,p); else update(rson,mid+1,r,p); pushup(x); } int ask(int x,int l,int r,int x0,int x1) { if(l==r) return l; int mid=(l+r)>>1; int sum0=x0+t[lson].x0,sum1=x1+t[lson].x1; if(max(sum0,sum1)>=max(t[1].x0-sum0,t[1].x1-sum1)) { return ask(lson,l,mid,x0,x1); } else { return ask(rson,mid+1,r,sum0,sum1); } } void qsum(int x,int l,int r,int L,int R) { if(L>R) return; if(l>=L&&r<=R) { X0+=t[x].x0; X1+=t[x].x1; return; } int mid=(l+r)>>1; if(L<=mid) qsum(lson,l,mid,L,R); if(R>mid) qsum(rson,mid+1,r,L,R); } int main() { // setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y), num[a[i].x]++; sort(a+1,a+1+n); build(1,1,M); for(i=1,j;i<=n;i=j) { j=i; while(j<=n&&a[j].y==a[i].y) update(1,1,M,a[j].x),++j; int pos=ask(1,1,M,0,0); X0=0,X1=0,qsum(1,1,M,1,pos); ans=min(ans,max(X0,X1)); X0=0,X1=0,qsum(1,1,M,1,pos-1); ans=min(ans,max(t[1].x0-X0,t[1].x1-X1)); } printf("%d\n",ans); return 0; }