文章標題 HRBUST 1400 : 汽車比賽(樹狀數組 )

汽車比賽

XianGe非常喜歡賽車比賽尤其是像達喀爾拉力賽,這種的比賽規模很大,涉及到很多國家的車隊的許多車手參賽。XianGe也夢想着自己能舉辦一個這樣大規模的比賽,XianGe幻想着有許多人蔘賽,那是人山人海啊,不過XianGe只允許最多100000人蔘加比賽。
這麼大規模的比賽應該有技術統計,在XianGe的比賽中所有車輛的起始點可能不同,速度當然也會有差異。XianGe想知道比賽中會出現多少次超車(如果兩輛車起點相同速度不同也算髮生一次超車)。

Input
本題有多組測試數據,第一行一個整數n,代表參賽人數,接下來n行,每行輸入兩個數據,車輛起始位置X i 和速度 V i(0< Xi,Vi <1000000)
Output
輸出比賽中超車的次數,每組輸出佔一行
Sample Input
2
2 1
2 2
5
2 6
9 4
3 1
4 9
9 1
7
5 5
6 10
5 6
3 10
9 10
9 5
2 2
Sample Output
1
6
7
題意:中文題幹。。。
分析:首先,如果一個人的速度大於另一個人的話,要使得有超車那就得這個人的位置比另一個人的位置要靠前或者同一位置。所以我們可以先按位置從大到小排序,位置一樣的按速度從小到大排序,然後用樹狀數組來維護每個速度的數量,然後枚舉每一個人,對於當前整個人,能超車的都是速度小於當前這個人的速度的,所以只要查找下比當前速度還小的前綴和就行了,這個操作就少樹狀數組的區間查詢,然後每次枚舉完一個人之後,還得將當前這個人的速度插入進樹狀數組,這個就是單點修改
代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
typedef long long ll;

const int mod=1e9+7;
const int maxn=1e5+10;

int tree[maxn];
int n;

struct node {
    int pos,v;
    bool operator <(const node & t)const {
        return pos>t.pos||(pos==t.pos&&v<t.v);
    } 
}a[maxn];

int lowbit(int x){
    return x&(-x);
}

int sum(int i){
    int s=0;
    while (i>0){
        s+=tree[i];
        i-=lowbit(i);
    }
    return s;
}

void add(int i,int val){
    while (i<=100000){
        tree[i]+=val;
        i+=lowbit(i);
    }
}

int main()
{
    while (scanf ("%d",&n)!=EOF){
        memset (tree,0,sizeof (tree));
        for (int i=0;i<n;i++){
            scanf ("%d%d",&a[i].pos,&a[i].v);
        }
        sort(a,a+n);
        ll ans=0;
        for (int i=0;i<n;i++){
            int tmp=a[i].v;
            add(tmp,1);
            ans+=sum(tmp-1);
        }
        printf ("%lld\n",ans);
    }
    return 0;
}
發佈了191 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章