E - 卿学姐与城堡的墙(树状数组求逆序数)

卿学姐与城堡的墙

Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

卿学姐终于来到了魔王的城堡,城堡修建的十分壮观。

即使心中放不下公主,卿学姐还是忍不住驻足观赏这宏伟的建筑。

卿学姐注意到城堡的墙上有若干直线状的花纹。

可以将墙看做一个平面,卿学姐想知道有多少种方式任取两个直线,使得这两个直线的交点的横坐标xx满足:uxvu≤x≤v。

Input

第一行三个整数N,u,vN,u,v,标明直线有NN条。

接下来有NN行,每行两个整数k,bk,b,表示这条直线是y=kx+by=kx+b

1N2000001≤N≤200000

0|k|10000000000≤|k|≤1000000000

0|b|10000000000≤|b|≤1000000000

0|u|10000000000≤|u|≤1000000000

0|v|10000000000≤|v|≤1000000000

输入保证uvu≤v,保证没有两条直线是一样的

Output

输出一个整数,代表选择的方法数。

Sample input and output

Sample InputSample Output
3 -3 1
-1 3
2 2
1 1
3

Hint

title

上图是样例的解释,交点是A,B,C

其实就是求逆序对数,先分别算出与u的交点和与v的交点,把u从小到大排序,然后依次把与v的交点加入树状数组,因为后加入的直线与u的交点肯定大于先加入直线与u的交点,所以后加入的直线与v的交点只要小于或者等于先加入的直线与v的交点就可以判断出必定相交,也就成了求逆序对数的问题了,还要离散化,因为数据范围都太大了。。。

#pragma GCC diagnostic error "-std=c++11"
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>

using namespace std;
typedef long long LL;
const int N = 200000 + 5;
struct Point{
    LL x, y;
    bool operator < (const Point &X) const{
        if(x != X.x) return x < X.x;
        return y > X.y;
    }
};

int c[N << 1];
vector<Point> a;
vector<LL> tot;

LL Query(int x){
    LL ret = 0;
    while(x){
        ret += c[x];
        x -= x&(-x);
    }
    return ret;
}

void change(int x){
    while(x <= (int)tot.size()){
        c[x]++;
        x += x&(-x);
    }
}

int main(){
    //std::ios::sync_with_stdio(false);
    LL n, u, v, b, k;
    cin >> n >> u >> v;
    for(int i = 0; i < n; i++){
        cin >> k >> b ;
        a.push_back((Point){k*u+b, k*v+b});
        tot.push_back(a[i].x);
        tot.push_back(a[i].y);
    }
    sort(tot.begin(), tot.end());

    tot.resize(distance(tot.begin(), unique(tot.begin(), tot.end())));

    for(Point &i:a){
        i.y = (LL)(lower_bound(tot.begin(), tot.end(), i.y) - tot.begin()) + 1;
        i.x = (LL)(lower_bound(tot.begin(), tot.end(), i.x) - tot.begin()) + 1;
    }

    sort(a.begin(), a.end());
    LL ans = 0;
    for(Point &i:a){
        ans += Query((int)tot.size()) - Query(i.y - 1);
        change(i.y);
    }
    cout << ans << endl;
}

 

posted @ 2017-08-23 15:57  Pretty9  阅读(266)  评论(0编辑  收藏  举报