题意:在一维坐标轴上给出 n 个人的起点和速度,问一共会出现多少次超越。
首先按照 x 排序,xi 右边速度比 xi 小的人都会被 xi 超越,因此可以从 x 最大的那个人开始,求速度的前缀和,表示这个人右边有多少人速度比他小,然后更新速度。
值得一提的是如果 x 相等,那么要先处理 v 大的那个,否则会影响结论。
#include<stack> #include<set> #include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<queue> #include<cstring> #include<string> #include<map> using namespace std; int n = 1000005; int a[1000005]; struct node{ int x,v; }N[1000005]; bool cmp(node a, node b){ if(a.x == b.x) return a.v>b.v; else return a.x < b.x; } int lowbit(int x){ return x&(-x); } void add(int pos , int num){ while(pos <= n){ a[pos] += num; pos += lowbit(pos); } } int sum(int n){ int sum = 0; while(n > 0){ sum += a[n]; n -= lowbit(n); } return sum; } int main(){ //freopen("a.txt", "r", stdin); int n; while(scanf("%d", &n) != EOF){ memset(a, 0, sizeof(a)); for(int i = 1; i <= n; i++) scanf("%d %d", &N[i].x, &N[i].v); sort(N+1, N+1+n, cmp); long long ans = 0; for(int i = n; i >= 1; i--){ ans += sum(N[i].v-1); add(N[i].v, 1); } cout << ans << endl; } return 0; }