13

NEU1438 Car race game(树状数组)

 3 years ago
source link: https://arminli.com/neu1438/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Armin's Blog

NEU1438 Car race game(树状数组)

February 17, 2016

题目链接

题意:在一维坐标轴上给出 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;
}

Profile picture

Written by Armin Li , a venture capitalist. [Weibo] [Subscribe]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK