結果

問題 No.2873 Kendall's Tau
ユーザー rogi52rogi52
提出日時 2024-09-06 23:00:56
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 257 ms / 4,500 ms
コード長 14,402 bytes
コンパイル時間 3,764 ms
コンパイル使用メモリ 271,616 KB
実行使用メモリ 31,272 KB
最終ジャッジ日時 2024-09-06 23:03:36
合計ジャッジ時間 8,929 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,944 KB
testcase_02 AC 2 ms
6,940 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 2 ms
6,940 KB
testcase_05 AC 2 ms
6,940 KB
testcase_06 AC 2 ms
6,940 KB
testcase_07 AC 235 ms
23,424 KB
testcase_08 AC 247 ms
29,364 KB
testcase_09 AC 234 ms
23,156 KB
testcase_10 AC 257 ms
31,272 KB
testcase_11 AC 231 ms
22,772 KB
testcase_12 AC 244 ms
28,644 KB
testcase_13 AC 68 ms
9,820 KB
testcase_14 AC 197 ms
26,624 KB
testcase_15 AC 39 ms
7,724 KB
testcase_16 AC 40 ms
7,432 KB
testcase_17 AC 172 ms
19,920 KB
testcase_18 AC 128 ms
17,104 KB
testcase_19 AC 167 ms
20,280 KB
testcase_20 AC 40 ms
8,108 KB
testcase_21 AC 135 ms
16,416 KB
testcase_22 AC 56 ms
9,376 KB
testcase_23 AC 137 ms
16,696 KB
testcase_24 AC 18 ms
6,944 KB
testcase_25 AC 36 ms
7,500 KB
testcase_26 AC 170 ms
18,904 KB
testcase_27 AC 103 ms
14,816 KB
testcase_28 AC 208 ms
25,628 KB
testcase_29 AC 209 ms
25,828 KB
testcase_30 AC 27 ms
6,940 KB
testcase_31 AC 54 ms
9,068 KB
testcase_32 AC 135 ms
17,060 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/data_structure/fenwick_tree.hpp"

template < class comm_monoid > class fenwick_tree {
  public:
    using T = typename comm_monoid::set;

  private:
    int n, n2;
    vector< T > data;

    int ceil_pow2(int n) {
        int x = 1;
        while(x < n) x <<= 1;
        return x;
    }

  public:
    fenwick_tree() : fenwick_tree(0) {}
    fenwick_tree(int n) : n(n), n2(ceil_pow2(n)), data(n + 1, comm_monoid::id()) { assert(comm_monoid::comm); }
    fenwick_tree(const vector< T > &a) : n(a.size()), n2(ceil_pow2(n)), data(a) {
        assert(comm_monoid::comm);
        data.insert(data.begin(), {comm_monoid::id()});
        for(int i = 1; i <= n; i++) {
            int p = i + (i & -i);
            if(p <= n) data[p] = comm_monoid::op(data[i], data[p]);
        }
    }

    void add(int i, T x) {
        for(int p = i + 1; p <= n; p += p & -p) data[p] = comm_monoid::op(data[p], x);
    }
    // [0, r)
    T fold(int r) {
        T s = comm_monoid::id();
        for(int p = r; p > 0; p -= p & -p) s = comm_monoid::op(data[p], s);
        return s;
    }
    // [l, r)
    T fold(int l, int r) {
        return comm_monoid::op(comm_monoid::inv(fold(l)), fold(r));
    }
    T get(int i) {
        return fold(i, i + 1);
    }
    void set(int i, T x) {
        add(i, comm_monoid::op(comm_monoid::inv(get(i)), x));
    }
    template< class func > int search(const func &f) {
        T s = comm_monoid::id();
        if(f(s)) return 0;
        int i = 0, k = n2;
        while(k >>= 1) {
            int p = i | k;
            if(p <= n && !f(comm_monoid::op(s, data[p]))) s = comm_monoid::op(s, data[i = p]);
        }
        return i;
    }
};
#line 1 "cp-library/src/algebra/sum.hpp"
template < class T > class sum_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return l + r; }
    static constexpr T id() { return T(0); }
    static constexpr T inv(const T &x) { return -x; }
    static constexpr T pow(const T &x, const ll n) { return x * n; }
    static constexpr bool comm = true;
};
#line 5 "A.cpp"

int main() {
#define int i64
    int N = in();
    vector<pair<int,int>> p(N);
    for(auto &[x, y] : p) x = in(), y = in();
    const auto [mx, my] = [&] {
        vector<int> vx, vy;
        for(auto [x, y] : p) {
            vx.push_back(x);
            vy.push_back(y);
        }
        unique(vx);
        unique(vy);
        for(auto &[x, y] : p) {
            x = lower_bound(vx, x);
            y = lower_bound(vy, y);
        }
        return pair<int,int>{vx.size(), vy.size()};
    }();

    i64 P = 0, Q = 0;
    vector<vector<int>> ys(mx);
    for(auto [x, y] : p) ys[x].push_back(y);
    fenwick_tree<sum_monoid<i64>> tree(my);
    for(int x : rep(mx)) {
        for(int y : ys[x]) {
            P += tree.fold(y);
            Q += tree.fold(y + 1, my);
        }
        for(int y : ys[x]) tree.add(y, +1);
    }

    auto f = [&](vector<int> v) {
        sort(v);
        vector<pair<int, int>> vec;
        const int m = v.size();
        vec.push_back({v[0], 1});
        for(int i : rep(1LL, m)) {
            if(vec.back().first == v[i]) vec.back().second++;
            else vec.push_back({v[i], 1});
        }
        i64 sum = 0;
        for(auto [_, c] : vec) sum += i64(c) * (c - 1) / 2;
        return i64(m) * (m - 1) / 2 - sum;
    };

    vector<int> X, Y;
    for(auto [x, y] : p) X.push_back(x), Y.push_back(y);
    const i64 R = f(X);
    const i64 S = f(Y);

    printer::precision(20);
    print(f64(P - Q) / sqrt(R) / sqrt(S));
}
0