Lights
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1146 Accepted Submission(s): 300
Problem Description
Today is April 1st, 2100. Now Guangzhou is a very very big city. Since the number of traffic accidents increased last month, the mayor asked Mr. Chopsticks to investigate the traffic condition of the city.
After studying the map of Guangzhou for a while, Mr. Chopsticks has some ideas. Guangzhou can be considered as a rectangular grid with 50000 horizontal streets running west-east (labeled with y-coordinates from 1 to 50000) and 50000 vertical streets running north-south (labeled with x-coordinates from 1 to 50000). All streets are two-way streets. A crossroad is an intersection of a horizontal street and a vertical street, so a crossroad can be represented by (x, y), where x and y are coordinates of the horizontal street and vertical street respectively. Since there are too many streets, traffic lights are not placed at all crossroads. Given two crossroads (x1, y1) and (x2, y2), a path between these two crossroads is said to be good if the length of the path is |x1 – x2| + |y1 – y2| and there exist a traffic light at each turn of this path. Of course, a path must be along the streets, and a turn can only be at a crossroad.
Now given locations of all traffic lights in Guangzhou, Mr. Chopsticks wants to check whether there exists at least one good path between every pair of traffic lights. As Mr. Chopsticks is busy in preparing ACMICPC 2100, he asks you for help.
Input
The input contains multiple test cases. Each case begins with an integer N (1 <= N <= 500000), indicating the number of traffic lights. The following N lines each contain two integers x and y (1 <= x, y <= 50000), indicating a location of a traffic light. There may be multiple traffic lights at the same location.
N = 0 indicates the end of the input.
Output
For each case, output “YES” if there exists at least one good path between every pair of traffic lights; otherwise output “NO”.
Sample Input
2
1 1
3 3
3
1 1
1 3
3 3
0
Sample Output
NO
YES
题目大意
在一个大小为50000*50000的矩形中,有n个路灯。(n<=500000)
询问是否每一对路灯之间存在一条道路,使得长度为|x1 – x2| + |y1 – y2|且每个拐弯点都是路灯。
将按x正这排序来一遍倒着排序来一遍
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 500010;
const int maxy = 50010;
map<int,int>mp;
map<int,int>near_x;
struct node
{
int x, y;
}st[maxn];
bool cmp(node a,node b){
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
struct tre
{
int chl,chr;
int cnt;
}t[1000010*8];
int root[maxn];
int tot = 0;
void build(int &x,int l,int r) {
x=++tot;
t[x].cnt = 0;
if (l==r) return ;
int mid=(l+r)>>1;
build(t[x].chl,l,mid); build(t[x].chr,mid+1,r);
}
void insert(int &x,int rot,int key,int l,int r) {
x=++tot;
t[x].chl=t[rot].chl;
t[x].chr=t[rot].chr;
t[x].cnt=t[rot].cnt+1;
if (l==r) {
return ;
}
int mid=(l+r)>>1;
if (key>mid) {
insert(t[x].chr,t[rot].chr,key,mid+1,r);
} else {
insert(t[x].chl,t[rot].chl,key,l,mid);
}
}
int query(int a,int b,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)return t[b].cnt - t[a].cnt;
int mid = (l+r)>>1;
int suml = 0;
int sumr = 0;
if(ql<=mid)suml = query(t[a].chl,t[b].chl,l,mid,ql,qr);
if(qr>mid)sumr = query(t[a].chr,t[b].chr,mid+1,r,ql,qr);
return suml+sumr;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
tot = 0;
mp.clear();
near_x.clear();
int num = 0;
for(int i = 0;i<n;i++)
{
scanf("%d%d",&st[i].x,&st[i].y);
}
sort(st,st+n,cmp);
for(int i = 0;i<n;i++)
{
if(!mp[st[i].x])
mp[st[i].x] = ++num;
}
build(root[0],1,50010);
int last = root[0];
bool flag = 1;
int near_rt;
int near_y;
for(int i = 0;i<n;i++)
{
if(i>0&&st[i].x==st[i-1].x&&st[i].y==st[i-1].y)continue;
insert(root[mp[st[i].x]],last,st[i].y,1,50010);
last = root[mp[st[i].x]];
near_rt = mp[near_x[st[i].y]];
if(i == 0||st[i].x!=st[i-1].x)near_y = 0;
else near_y = st[i-1].y;
if(near_y+1<=st[i].y-1&&query(root[near_rt],root[mp[st[i].x]],1,50010,near_y+1,st[i].y-1))
{
flag = false;
break;
}
near_x[st[i].y] = st[i].x;
}
for(int i = 0;i<n;i++)st[i].x = 50001-st[i].x;
sort(st,st+n,cmp);
mp.clear();
near_x.clear();
for(int i = 0;i<n;i++)
{
if(!mp[st[i].x])
mp[st[i].x] = ++num;
}
tot = 0;
build(root[0],1,50000);
last = root[0];
for(int i = 0;i<n;i++)
{
if(i>0&&st[i].x==st[i-1].x&&st[i].y==st[i-1].y)continue;
insert(root[mp[st[i].x]],last,st[i].y,1,50010);
last = root[mp[st[i].x]];
near_rt = mp[near_x[st[i].y]];
if(i == 0||st[i].x!=st[i-1].x)near_y = 0;
else near_y = st[i-1].y;
if(near_y+1<=st[i].y-1&&query(root[near_rt],root[mp[st[i].x]],1,50010,near_y+1,st[i].y-1))
{
flag = false;
break;
}
near_x[st[i].y] = st[i].x;
}
if(!flag)
printf("NO\n");
else
printf("YES\n");
}
}