Kattis - intersectingrectangles 扫描线+线段树
题目:https://open.kattis.com/problems/intersectingrectangles
题意::给你n个矩形,每一个矩形给你这个矩形的左下角的坐标和右上角的坐标,然后问你这些矩形会不会相交,如果存在相交的点,输出1,否则输出0。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define pb push_back #define lson root<<1,l,midd #define rson root<<1|1,midd+1,r const int M=2e5+5; struct node{ int l,r,h,flag; }a[M]; bool cmp(node p,node q){ return p.h<q.h; } int lisan[M<<2],tot1,tot2; int tree[M<<2]; void up(int root){ tree[root]=tree[root<<1]+tree[root<<1|1]; } void update(int p,int delta,int root,int l,int r) { if(l==r) { tree[root]+=delta; return ; } int midd=(l+r)>>1; if(p<=midd)update(p,delta,lson); else update(p,delta,rson); up(root); } int query(int L,int R,int root,int l,int r) { if(L<=l&&r<=R)return tree[root]; //cout<<l<<"(("<<r<<endl; int midd=(l+r)>>1,res=0; if(L<=midd)res+=query(L,R,lson); if(R>midd)res+=query(L,R,rson); return res; } int main(){ int n; scanf("%d",&n); for(int x1,x2,y1,y2,i=1;i<=n;i++){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); a[++tot1]=node({x1,x2,y1,1});///1代表上边界 a[++tot1]=node({x1,x2,y2,-1});///-1代表下边界 // lisan[tot2++]=x1-1; // lisan[tot2++]=x1+1; lisan[++tot2]=x1; // lisan[tot2++]=x2-1; lisan[++tot2]=x2; // lisan[tot2++]=x2+1; } // cout<<tot1<<"@@"<<tot2<<endl; sort(a+1,a+1+tot1,cmp); sort(lisan+1,lisan+tot2+1); int m=unique(lisan+1,lisan+1+tot2)-lisan-1; int ans=0; for(int i=0;i<tot1;i++){ node u=a[i]; int x=lower_bound(lisan+1,lisan+1+m,u.l)-lisan; int y=lower_bound(lisan+1,lisan+1+m,u.r)-lisan; /// cout<<x<<"~~~"<<y<<endl; if(u.flag==1)///因为是上边界,所以要在更新前加边,才不会误判 ans|=(query(x,y,1,1,2*n)!=0); update(x,u.flag,1,1,2*n); update(y,u.flag,1,1,2*n); if(u.flag==-1) ans|=(query(x,y,1,1,2*n)!=0); } printf("%d\n",ans!=0); return 0; }