您的位置:首页 > 其它

codeforces 260E Dividing Kingdom(函数式线段树)

2012-12-28 15:48 78 查看
题目链接:http://codeforces.com/problemset/problem/260/E

题意:给出二维平面上一些点,画出四条线,两条平行于X轴两条平行于Y轴,将平面分为9块,使得每块中的点个数为给定的9个数。

思路:按照Y坐标建立线段树。枚举9个数的位置,判断可行性。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;

struct node
{
int a,b,L,R,s,mid;
};

const int INF=1000000000;
const int M=100005;
node t[M<<6];
int root[M],tot;
int n,q[M];

struct point
{
int x,y;
};

point p[M];

int cmp(point a,point b)
{
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}

int find(int low,int high,int p[],int key)
{
int mid;
while(low<=high)
{
mid=(low+high)>>1;
if(p[mid]==key) break;
if(p[mid]>key) high=mid-1;
else low=mid+1;
}
return mid;
}

int build(int a,int b)
{
int k=++tot;
t[k].a=a;
t[k].b=b;
t[k].s=0;
t[k].mid=(a+b)/2;
if(a!=b)
{
t[k].L=build(a,t[k].mid);
t[k].R=build(t[k].mid+1,b);
}
return k;
}

int change(int p,int x,int s)
{
int k=++tot;
t[k]=t[p];
t[k].s+=s;
if(t[k].a==x&&t[k].b==x) return k;
if(x<=t[k].mid) t[k].L=change(t[p].L,x,s);
else t[k].R=change(t[p].R,x,s);
return k;
}

int query(int p,int q,int k)
{
if(t[q].a==t[q].b) return t[q].a;
int x=t[t[q].L].s-t[t[p].L].s;
if(k<=x) return query(t[p].L,t[q].L,k);
return query(t[p].R,t[q].R,k-x);
}

int data[9],visit[9],S[9];

int getKth(int L,int R,int k)
{
return query(root[L],root[R],k);
}

int OK()
{
int Left=S[0]+S[1]+S[2];
int Mid=Left+S[3]+S[4]+S[5];
if(p[Left-1].x==p[Left].x||p[Mid-1].x==p[Mid].x) return 0;

int L0=-INF,R0=INF;
L0=max(L0,getKth(0,Left,S[0]));
R0=min(R0,getKth(0,Left,S[0]+1));
if(R0-L0<1) return 0;
L0=max(L0,getKth(Left,Mid,S[3]));
R0=min(R0,getKth(Left,Mid,S[3]+1));
if(R0-L0<1) return 0;
L0=max(L0,getKth(Mid,n,S[6]));
R0=min(R0,getKth(Mid,n,S[6]+1));
if(R0-L0<1) return 0;

int L1=-INF,R1=INF;
L1=max(L1,getKth(0,Left,S[0]+S[1]));
R1=min(R1,getKth(0,Left,S[0]+S[1]+1));
if(R1-L1<1) return 0;
L1=max(L1,getKth(Left,Mid,S[3]+S[4]));
R1=min(R1,getKth(Left,Mid,S[3]+S[4]+1));
if(R1-L1<1) return 0;
L1=max(L1,getKth(Mid,n,S[6]+S[7]));
R1=min(R1,getKth(Mid,n,S[6]+S[7]+1));
if(R1-L1<1) return 0;

int x1=(p[Left-1].x+p[Left].x)/2;
int x2=(p[Mid-1].x+p[Mid].x)/2;
int y1=(q[L0]+q[R0])/2;
int y2=(q[L1]+q[R1])/2;
printf("%d.5 %d.5\n",x1,x2);
printf("%d.5 %d.5\n",y1,y2);
return 1;
}

int DFS(int dep)
{
if(dep==9) return OK();
int i;
for(i=0;i<9;i++) if(!visit[i])
{
visit[i]=1;
S[dep]=data[i];
if(DFS(dep+1)) return 1;
visit[i]=0;
}
return 0;
}

int main()
{
while(scanf("%d",&n)!=-1)
{
tot=0;
int i,k;
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
q[i]=p[i].y;
}
sort(p,p+n,cmp);
sort(q,q+n);
k=unique(q,q+n)-q;
for(i=0;i<n;i++) p[i].y=find(0,k-1,q,p[i].y);
root[0]=build(0,k-1);
for(i=0;i<n;i++) root[i+1]=change(root[i],p[i].y,1);
for(i=0;i<9;i++) scanf("%d",data+i);
memset(visit,0,sizeof(visit));
if(!DFS(0)) puts("-1");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: