Comet OJ - 2019國慶歡樂賽 C題 兩排房子

###題目連接###ios

 

題目大意:這裏有橫着的兩排房子,給你每一個房子的左端點和右端點。若兩排房子中分別有兩個房子 x y ,他們在橫座標上有重疊部分(端點重疊也算),則被稱爲 「對門」 關係。spa

問你總共有多少個 「對門」 關係。code

 

分析:blog

顯然題目要讓你求的是,枚舉第一排各個房子,而後找第二排有多少個房子區間與之有交集部分。排序

第一排:               [                     ]get

第二排:[      ]   [         ]  [   ]  [             ]    it

 

畫一下能夠看出:將第二排的房子以左端點從小到大排序後,對應找第一排某個房子的貢獻,只須要找到第一排的這個房子的區間內,能括起來多少個房子便可。io

因爲只要有重疊就算,故假設第一排的某個房子的左右端點爲 a  b ,第二排的某個房子中,左右端點爲 x y ,那麼只要在第二排中二分:class

一、找到第一個大於等於 a 的 y ,而後記下起點標號 st 。test

二、找到最後一個小於等於 b 的 x ,而後記下終點標號 en。

故第一排這個房子所能提供的貢獻爲:en - st + 1

 

代碼以下:

#include<iostream> #include<algorithm>
using namespace std; typedef long long ll; int n,m; ll ans; struct Node{ int l,r; Node(){}; Node(int _l,int _r){ l=_l,r=_r; } }a[400008]; bool cmp1(Node q,Node w){ return q.l<w.l; } bool cmp2(Node q,Node w){ return q.r<w.r; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].l,&a[i].r); } sort(a+1,a+n+1,cmp1); int A,B; for(int i=1;i<=m;i++){ scanf("%d%d",&A,&B); int st=lower_bound(a+1,a+n+1,Node(0,A),cmp2)-a; int en=upper_bound(a+1,a+n+1,Node(B,0),cmp1)-a-1; ans+=1ll*(en-st)+1ll; } printf("%lld\n",ans ); }
相關文章
相關標籤/搜索