codeforces 260E Dividing Kingdom(函数式线段树)
2012-12-28 15:48
78 查看
题目链接:http://codeforces.com/problemset/problem/260/E
题意:给出二维平面上一些点,画出四条线,两条平行于X轴两条平行于Y轴,将平面分为9块,使得每块中的点个数为给定的9个数。
思路:按照Y坐标建立线段树。枚举9个数的位置,判断可行性。
题意:给出二维平面上一些点,画出四条线,两条平行于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; }
相关文章推荐
- hdu4866(函数式线段树)
- Codeforces 838B. Diverging Directions (LCA+线段树, IndiaHacks 2nd Elimination 2017 )
- codeforces 383C Propagating tree 线段树
- codeforces 374D 树状数组或者线段树
- CodeForces 19D Points (线段树+set)
- CodeForces - 668D Little Artem and Time Machine(线段树||树状数组)
- CodeForces 228D. Zigzag(线段树暴力)
- Codeforces-446(Div.2)-B-Wrath--(线段树区间更新)
- Codeforces 46D Parking Lot(线段树)
- [线段树 杂题] Codeforces 806E VK Cup 2017 Round 3 E. Blog Post Rating
- CodeForces 558E(计数排序+线段树优化)
- CodeForces - 816B Karen and Coffee (线段树的区间插入+单点查询)
- codeforces 444C. DZY Loves Colors (线段树)
- 线段树 CodeForces 220B - Little Elephant and Array
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
- codeforces 85D. Sum of Medians(线段树or分块)
- [Usaco2014 Open Gold ]Cow Optics (树状数组+扫描线/函数式线段树)
- Codeforces 629D Babaei and Birthday Cake(线段树优化dp)
- CodeForces 35E Parade(线段树区间更新+离散化)
- 【模板】主席树/函数式线段树/可持久化线段树