CF 472 div1 D. Contact ATC

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
const int N = 1e5 + 5;

struct fraction {
    long long num, deno;
    template <typename T>
    static inline T gcd(const T a, const T b) {
        return (b == 0) ? a : gcd(b, a % b);
    }
    fraction() {}
    inline void simplify() {
        if (deno < 0) {
            num *= -1;
            deno *= -1;
        }
        long long g = gcd(num < 0 ? -num : num, deno);
        num /= g;
        deno /= g;
    }
    fraction(long long _num, long long _deno) : num(_num), deno(_deno) { simplify(); }
    inline bool operator<(const fraction& rhs) const { return num * rhs.deno < deno * rhs.num; }
    inline bool operator!=(const fraction& rhs) const { return num * rhs.deno != deno * rhs.num; }
};
std::pair<fraction, fraction> T[N];
std::pair<fraction, int> D[N];
int p[N];
int X[N], V[N];

int bitTree[N];
void add(int pos, int num) {
    for (int i = ++pos; i < N; i += (i & -i)) {
        bitTree[i] += num;
    }
}
int sum(int pos) {
    int result = 0;
    for (int i = ++pos; i; i -= (i & -i)) {
        result += bitTree[i];
    }
    return result;
}

int main() {
    int n, w;
    while (~scanf("%d %d", &n, &w)) {
        for (int i = 0; i < n; ++i) {
            scanf("%d %d", &X[i], &V[i]);
        }
        for (int i = 0; i < n; ++i) {
            long long v1 = V[i] - w;
            long long v2 = V[i] + w;
            T[i] = {fraction(-X[i], v1), fraction(-X[i], v2)};
        }

        for (int i = 0; i < n; ++i) {
            T[i].second.num *= -1;
        }
        std::sort(T, T + n);  //-w increase and w descend
        for (int i = 0; i < n; ++i) {
            T[i].second.num *= -1;
        }
        for (int i = 0; i < n; ++i) {
            D[i] = {T[i].second, i};
        }
        std::sort(D, D + n);
        for (int i = 0, rk = -1; i < n; ++i) {
            if ((i == 0) || D[i].first != D[i - 1].first)
                ++rk;
            p[D[i].second] = rk;
        }

        long long ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += sum(N - 1) - sum(p[i] - 1);
            add(p[i], 1);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Basasuya/p/8836586.html

时间: 2024-08-04 02:50:43

CF 472 div1 D. Contact ATC的相关文章

CF#462 div1 D:A Creative Cutout

CF#462 div1 D:A Creative Cutout 题目大意: 原网址戳我! 题目大意: 在网格上任选一个点作为圆中心,然后以其为圆心画\(m\)个圆. 其中第\(k\)个圆的半径为\(\sqrt{k}\),\(m\)个圆的编号依次为\(1\)~\(m\). 定义一个格点的美妙值\(g(x,y)\)为包含了它的所有圆的编号之和. 定义\(f(n)\)为:当画了\(n\)个圆时,\(f(n) = \sum_{i,j\in R} g(i,j)\). 现在非常变态的问你一个非常无聊的恶心问

CF#345 (Div1)

身败名裂后的题解 先吐槽一下自己的代码能力&手速 A 06:52交的 B 29:34交的 C 52:49交的 开始一切正常 然后01:15左右发现C看起来是100W会爆栈,吓得我改成VC++开大了栈重交了一遍 于是赶紧去room里扫一波,然后发现一群用dfs的,感觉高兴极了,开始hack,然后成功-2-最后这些人system test都过啦- 我得赶紧去看一下CF的栈空间是多大啊 UPD: 我以后cf做题再也不管栈空间了-系统栈默认256M- 然后01:46的时候发现A有个地方没开long lo

CF #349 div1 B. World Tour

题目链接:http://codeforces.com/problemset/problem/666/B 大意是给一张有向图,选取四个点,使得走这四个点,任意两个点之间走最短路,总距离最长. 3000个点直接floyd肯定不行,但是注意到任意每条路距离都是1,其实可以枚举所有源点作bfs,求出距离数组. 然后对于每个点求出以这个点为入点和出点距离最大的3个点.再根据这个信息,枚举四个点中的中间两个,再枚举这两个点距离他们最远的那3*3种情况,判断是否有重复,没有重复的话,更新答案. 1 #incl

CF #228 div1 B. Fox and Minimal path

题目链接:http://codeforces.com/problemset/problem/388/B 大意是用不超过1000个点构造一张边权为1的无向图,使得点1到点2的最短路的个数为给定值k,其中k为不超过1e9的正整数,输出邻接矩阵 构造方法也不止一种 有一种分层构造方法是这样的, 第i层的点与1号点距离为i-1 第一层放置1号点 第二层放置3号和4号点,分别与上一层的1号点相连,他们的最短路为1,且个数也为1 接下来每一层都会比上一层的点数要多1,第i+1层,首先与第i层的前i个点相连,

Codeforces956D. Contact ATC

$n \leq 100000$个飞机在坐标轴上,给坐标给速度,坐标速度异号,还有一个风速在$[-w,w]$区间,$w$比最小的速度绝对值要小.由于风速不知道,所以问有多少对飞机可能在原点相遇. 思维定势:$\frac{x_i}{v_i+v}=\frac{x_j}{v_j+v}$,$v$是风速,然后推下去,会推到一个三维偏序.. 没有观察题目性质.这个时间是关于风速单调而连续的,所以只要风速最小和风速最大这两个东西求个逆序对就行了. 似乎卡精度,用了分数. 这种题要写题解感觉最近脑子有点锈..有没

codeforces #305 div1 done

总算搞定了这一场比赛的题目,感觉收获蛮大 其中A,B,C都能通过自己的思考解决掉 D题思路好神,E题仔细想想也能想出来 以后坚持每两天或者一天做一场CF的div1的全套题目 除非有实在无法做出来的题目,每道题目还是都要写题解的 (我这算不算立flag? 本蒟蒻写的题解的链接: A:http://www.cnblogs.com/joyouth/p/5352953.html B:http://www.cnblogs.com/joyouth/p/5352932.html C:http://www.cn

Codeforces Round #472 (based on VK Cup 2018 Round 2)解题报告

A. Mystical Mosaic 题目大意: 给一个空白矩阵,每次可以选一些行和一些列并让他们的交点涂黑,每次选的行和列不能有交集. 给出最后的矩阵样子,问能不能经过若干次以上操作后得到最后的矩阵. 思路: 每一行都可以确定哪些列必须被覆盖记为Si,任意两个不同的行之间要么S相等要么相交为空集. 所以我们要做的就是确定任意两行,他们的S要么相等要么相交为空集,这是答案为Yes的充要条件. 代码: 1 #include <bits/stdc++.h> 2 using namespace st

cf训练2

CF 616 div1 A 题解 若 \(k \geq m-1\) ,我们可以任意指定顺序,我们求每个方案的最大值即可. 若 \(k < m-1\) ,发现我们有 \(m - k\) 种可能,取最小值即可. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; int read

2018暑期做题部分整合

<Matrix>(HDU) 题意:n*m矩阵,每个点可黑可白,问有多少种方案使矩阵至少有A行B列全黑. 思路:第一反应当然是容斥,但是发现a+1行全黑的方案,并不是恰被a行全黑的方案多算a次,所以直接+1,-1,+1,-1这样的容斥系数就不可行. 而如果DP,复杂度太高,不可行. 于是考虑手推容斥系数,a行全黑的方案,被计数的次数取为([a>=A]-被更小的a计算次数)即可. 收获:对于复杂的计数问题,如果分类时,一种方案会在若干类中重复计数,可以使用推广的容斥来做. <Alway