The 2012 ACM-ICPC Asia Changchun Regional Contest-J
题目大一就是去掉某一些使得两个点在同一矩形内,然后问有还剩多少矩形。
实际就是可以搞出一棵二叉树,生成的过程就是矩形分开的过程。然后答案显然就是 叶子节点个数---A和B的LCA为根的子树形的叶节点个数+1。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAXN 3000
using namespace std;
struct Rect{
int x1,x2,y1,y2;
int l,r,sonCnt;
}R[MAXN];
struct Segment{
int x1,x2,y1,y2;
}p[MAXN];
struct Point{
int x,y;
}A,B;
int N,Q,tot;
bool innerLine(int v,int L,int R){
return (v>=L && v<=R);
}
int buildTree(Rect node , int flag){
R[tot]=node;
R[tot].l=R[tot].r=-1;
R[tot].sonCnt=0;
int res = tot++;
for (int i=0;i<N;++i)
if ((p[i].y1==p[i].y2)^flag){
if (!flag) {
if (p[i].x1==node.x1 && p[i].x2==node.x2 && innerLine(p[i].y1,node.y1,node.y2))
{
Rect temp = node;
temp.y1=p[i].y1;
R[res].l= buildTree(temp,!flag);
temp = node;
temp.y2=p[i].y2;
R[res].r= buildTree(temp,!flag);
}
} else
{
if (p[i].y1==node.y1 && p[i].y2==node.y2 && innerLine(p[i].x1,node.x1,node.x2))
{
Rect temp = node;
temp.x1=p[i].x1;
R[res].l= buildTree(temp,!flag);
temp= node;
temp.x2=p[i].x2;
R[res].r= buildTree(temp,!flag);
}
}
}
if (R[res].l==-1 && R[res].r==-1) R[res].sonCnt=1;else
{
if (R[res].l!=-1) R[res].sonCnt=R[R[res].l].sonCnt;
if (R[res].r!=-1) R[res].sonCnt+=R[R[res].r].sonCnt;
}
return res;
}
bool innerRect(Point C,Rect R){
return (C.x>=R.x1 && C.x<=R.x2 && C.y>=R.y1 && C.y<=R.y2);
}
int DFS(Rect node){
if (node.l!=-1){
if (innerRect(A,R[node.l]) && innerRect(B,R[node.l]))
return DFS(R[node.l]);
}
if (node.r!=-1){
if (innerRect(A,R[node.r]) && innerRect(B,R[node.r]))
return DFS(R[node.r]);
}
return node.sonCnt;
}
int main()
{
while (cin>>R[0].x1>>R[0].y1>>R[0].x2>>R[0].y2){
cin>>N>>Q;
for (int i=0;i<N;++i){
scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
if (p[i].x1>p[i].x2) swap(p[i].x1,p[i].x2);
if (p[i].y1>p[i].y2) swap(p[i].y1,p[i].y2);
}
tot=0;
buildTree(R[0],0);
for (int i=0;i<Q;++i){
scanf("%d%d%d%d",&A.x,&A.y,&B.x,&B.y);
cout<<N+2-DFS(R[0])<<endl;
}
}
return 0;
}