###題目連接###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 ); }