题解 AT1279 【How are you?】

TRZ_2007

2020-10-18 14:05:27

Solution

- 题目传送门:[AT1279 How are you?](https://www.luogu.com.cn/problem/AT1279) # Description 给你 $n$ 段区间,求对于一个区间来说,**左端点比它大且与它有交**的区间个数。 $n \le 10^5$。 # Solution 观察到 $n \le 10^5$ ,很自然就会想到 $\mathcal{O(n)}$ 或者 $\mathcal{O(n\log n)}$ 的做法,这题要求区间的交,因此我们需要对所有的区间进行**左端点从小到大**排序,然后计算出**第一个左端点比它小**的区间的位置,减去该区间位置即为所求。 # Code ```cpp #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 9; struct node { int x,y,id; }a[N]; int n,f[N]; bool cmp1(node u,node v) { if(u.x == v.x) return u.y < v.y; return u.x < v.x; } bool cmp2(node u,node v) { return u.id < v.id; } int find(int x) { int l = 1,r = n,ans; while(l <= r) { int mid = (l + r) >> 1; if(a[mid].x <= x) { l = mid + 1; ans = mid; }else { r = mid - 1; } } return ans; } int main() { scanf("%d",&n); for(int i = 1;i <= n;i++) { scanf("%d %d",&a[i].x,&a[i].y); a[i].id = i; } sort(a + 1,a + n + 1,cmp1); for(int i = 1;i <= n;i++) { int t = find(a[i].y); f[a[i].id] = t - i; } sort(a + 1,a + n + 1,cmp2); for(int i = 1;i <= n;i++) { printf("%d\n",f[i]); } return 0; } ```