题目链接:
G - Intersecting Rectangles
Kattis - intersectingrectangles
题目大意:给你n个矩形,每一个矩形给你这个矩形的左下角的坐标和右上角的坐标,然后问你这些矩形会不会相交,如果存在相交的点,输出1,否则输出0。
具体思路:扫描线,我们首先对x进行排序,然后判断当前x直线对应的线段上是否有x已经覆盖,如果已经有就证明存在相交的情况。但是这样会存在多算的情况,所以我们对于每一个矩形的左端点打一个标记,然后右端点再打一个标记,当左端点的时候,先询问,再去更新。对于右端点,先更新,再去询问。
感谢lxw的讲解。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 4e5+100; 5 int tree[maxn<<2]; 6 struct node{ 7 int y1,y2,x,flag; 8 node(){} 9 node(int xx,int yy,int zz,int kk){ 10 y1=xx; 11 y2=yy; 12 x=zz; 13 flag=kk; 14 } 15 bool friend operator <(node t1,node t2){ 16 return t1.x<t2.x; 17 } 18 }q[maxn<<2]; 19 int lowbit(int t){ 20 return t&(-t); 21 } 22 int ask(int t){ 23 int ans=0; 24 while(t){ 25 ans+=tree[t]; 26 t-=lowbit(t); 27 } 28 return ans; 29 } 30 void update(int pos,int val){ 31 while(pos<=4e5+100){ 32 tree[pos]+=val; 33 pos+=lowbit(pos); 34 } 35 } 36 vector<int>w; 37 int main(){ 38 int n; 39 scanf("%d",&n); 40 int x1,y1,x2,y2; 41 for(int i=1;i<=n;i++){ 42 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 43 q[i]=node(y1,y2,x1,1); 44 q[i+n]=node(y1,y2,x2,-1); 45 w.push_back(x1); 46 w.push_back(x2); 47 w.push_back(y1); 48 w.push_back(y2); 49 } 50 sort(w.begin(),w.end()); 51 sort(q+1,q+2*n+1); 52 int k=0; 53 for(int i=1;i<=2*n;i++){ 54 int l=lower_bound(w.begin(),w.end(),q[i].y1)-w.begin()+1; 55 int r=lower_bound(w.begin(),w.end(),q[i].y2)-w.begin()+1; 56 if(q[i].flag==1){ 57 if(ask(r)-ask(l)>0){ 58 k=1; 59 break; 60 } 61 update(l,1); 62 update(r,1); 63 } 64 else { 65 update(l,-1); 66 update(r,-1); 67 if(ask(r)-ask(l)>0){ 68 k=1; 69 break; 70 } 71 } 72 } 73 if(k){ 74 printf("1 "); 75 } 76 else { 77 printf("0 "); 78 } 79 return 0; 80 }