链接:戳这里
Lights
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
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|且每个拐弯点都是路灯。
思路:
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<iomanip>
#include<cmath>
#include<bitset>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
#define INF (1ll<<60)-1
#define Max 8000000
using namespace std;
int n;
struct point{
int x,y;
point (int x=0,int y=0):x(x),y(y){}
bool operator < (const point &a)const{
if(x==a.x) return y<a.y;
return x<a.x;
}
}s[1000100];
bool operator == (const point &a,const point &b){
if(a.x==b.x && a.y==b.y) return true;
return false;
}
struct node{
int l,r,sum;
}tr[Max];
int tot;
void build(int &root,int l,int r){
root=++tot;
tr[root].l=l;
tr[root].r=r;
tr[root].sum=0;
if(l==r) return ;
int mid=(l+r)/2;
build(tr[root].l,l,mid);
build(tr[root].r,mid+1,r);
tr[root].sum=tr[tr[root].l].sum+tr[tr[root].r].sum;
}
void update(int &root,int l,int r,int last,int x,int v){
root=++tot;
if(l==r){
tr[root].sum=tr[last].sum+v;
return ;
}
tr[root].l=tr[last].l;
tr[root].r=tr[last].r;
int mid=(l+r)/2;
if(x<=mid) update(tr[root].l,l,mid,tr[last].l,x,v);
if(x>mid) update(tr[root].r,mid+1,r,tr[last].r,x,v);
tr[root].sum=tr[tr[root].l].sum+tr[tr[root].r].sum;
}
int query(int root,int l,int r,int x,int y){
if(x<=l && y>=r){
return tr[root].sum;
}
int mid=(l+r)/2;
if(y<=mid) return query(tr[root].l,l,mid,x,y);
else if(x>mid) return query(tr[root].r,mid+1,r,x,y);
else return query(tr[root].l,l,mid,x,mid)+query(tr[root].r,mid+1,r,mid+1,y);
}
int root[Max],flag=0;
int mx[50100],my[50100];/// 当前点正左方最近的x 正下方最近的y
void gao(){
tot=0;
mst(mx,0);
mst(my,0);
build(root[0],1,50000);
int last=root[0];
for(int i=1;i<=n;i++){
int x1=s[i].x , y1=s[i].y;
int x2=s[my[y1]].x , y2=s[mx[x1]].y;
update(root[x1],1,50000,last,y1,1);
int num1=query(root[x1],1,50000,y2+1,y1);
int num2=query(root[x2],1,50000,y2+1,y1);
if(num1!=num2+1) {
flag=1;
return ;
}
mx[s[i].x]=i; my[s[i].y]=i; last=root[x1];
}
}
int main(){
while(scanf("%d",&n)!=EOF){
if(n==0) break;
for(int i=1;i<=n;i++) scanf("%d%d",&s[i].x,&s[i].y);
sort(s+1,s+n+1);
int cnt=0;
for(int i=1;i<=n;i++){
if(s[i]==s[i+1]) continue;
s[++cnt]=s[i];
}
n=cnt;
flag=0;
gao();
for(int i=1;i<=n;i++) s[i].x=50001-s[i].x;
sort(s+1,s+n+1);
gao();
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}
/*
1 1 0 0
1 3 0 1
3 3 1 0
49998 3 0 0
50000 1 0 0
50000 3 49998 1
3
1 1
1 3
3 3
*/