結果

問題 No.2382 Amidakuji M
ユーザー CoCo_Japan_panCoCo_Japan_pan
提出日時 2023-07-14 23:09:41
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 4,265 bytes
コンパイル時間 3,092 ms
コンパイル使用メモリ 220,336 KB
実行使用メモリ 6,940 KB
最終ジャッジ日時 2024-09-16 08:18:24
合計ジャッジ時間 4,851 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 21 ms
5,376 KB
testcase_04 AC 36 ms
6,400 KB
testcase_05 WA -
testcase_06 WA -
testcase_07 RE -
testcase_08 AC 2 ms
5,376 KB
testcase_09 RE -
testcase_10 AC 45 ms
6,656 KB
testcase_11 WA -
testcase_12 RE -
testcase_13 AC 2 ms
5,376 KB
testcase_14 AC 2 ms
5,376 KB
testcase_15 AC 2 ms
5,376 KB
testcase_16 AC 2 ms
5,376 KB
testcase_17 AC 2 ms
5,376 KB
testcase_18 AC 2 ms
5,376 KB
testcase_19 WA -
testcase_20 AC 49 ms
6,940 KB
testcase_21 AC 52 ms
6,940 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/template/procon.hpp"

#ifndef DEBUG
// 提出時にassertはオフ
#ifndef NDEBUG
#define NDEBUG
#endif
// 定数倍高速化
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;

#define ALL(x) (x).begin(), (x).end()
template <class T>
using vec = vector<T>;
template <class T, class S>
inline bool chmax(T &a, const S &b) {
    return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
    return (a > b ? a = b, 1 : 0);
}
template <class T>
constexpr T INF = 1'000'000'000;
template <>
constexpr int INF<int> = 1'000'000'000;
template <>
constexpr ll INF<ll> = ll(INF<int>) * INF<int> * 2;
#line 3 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/data-structure/DualSegmentTree.hpp"

// 区間更新、一点取得を行う ただし作用は可換(RUQならタイムスタンプを付けるなどする)
// つまり区間更新を通常のセグ木の区間取得と同様に行う
template <class CommutativeMap>
class DualSegTree {
    // CommutativeMap::S 要素の型
    // CommutativeMap::F 作用の型
    // CommutativeMap::mapping S(F f, S x) 要素xに作用fを作用させる
    // CommutativeMap::id F() 恒等写像
    // CommutativeMap::composition F(F f, F g) 作用の合成 可換!
    using M = CommutativeMap;
    using F = typename M::F;
    using S = typename M::S;
    static_assert(std::is_convertible_v<decltype(&M::mapping), std::function<S (F, S)>>, "mapping S(F, S) type error");
    static_assert(std::is_convertible_v<decltype(&M::id), std::function<F()>>, "id F() type error");
    static_assert(std::is_convertible_v<decltype(&M::composition), std::function<F (F, F)>>,
                  "composition F(F, F) type error");
   public:
    explicit DualSegTree(int _N, const S& init) : N(_N), data(_N, init) {
        leaf = 1;
        while(leaf < N) {
            leaf <<= 1;
        }
        lazy.assign(leaf * 2, M::id());
    }
    // data[p] = x
    void set(int p, const S& x) {
        assert(0 <= p && p < N);
        data[p] = x;
    }
    // 区間[l, r)に作用fを適用
    void apply(int l, int r, const F & f) {
        assert(0 <= l && l <= r && r <= N);
        // logN個のlazyノードに分配
        l += leaf; r += leaf;
        while(l < r) {
            if(l & 1) {
                lazy[l] = M::composition(lazy[l], f);
                ++l;
            }
            if(r & 1) {
                --r;
                lazy[r] = M::composition(lazy[r], f);
            }
            l >>= 1;
            r >>= 1;
        }
    }
    // a[p]を取得 上のノードlogN個を作用させて返す
    S get(int p) const {
        assert(0 <= p && p < N);
        int index = p + leaf;
        F fmap = M::id();
        while(index > 0) {
            fmap = M::composition(fmap, lazy[index]);
            index >>= 1;
        }
        return M::mapping(fmap, data[p]);
    }
    private:
    const int N; // 考える要素数
    vec<F> lazy; // 可換な写像の完全二分木
    vec<S> data; // 実際の値
    int leaf; // 葉の数
};
#line 3 "main.cpp"

struct rangeAddOne {
    using S = int;
    using F = int;
    static S mapping(F f, S x) {
        return f + x;
    }
    static F id() {
        return 0;
    }
    static F composition(F f, F g) {
        return f + g;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int N;
    ll M;
    cin >> N >> M;
    vec<int> P(N);
    for(int &p : P) {
        cin >> p;
        --p;
    }
    DualSegTree<rangeAddOne> dual(N, 0);
    // まず最小の回数を数える
    ll cnt = 0;
    for(int i = 0; i < N - 1; i++) {
        cnt += dual.get(P[i]) + (P[i] - i);
        dual.apply(i, dual.get(P[i]) + P[i], 1);
    }
    ll ans = -1;
    if(cnt == 0) {
        ans = 0;
    } else {
        ll smallestM = (cnt + M - 1) / M * M;
        if((smallestM - cnt) % 2 == 0) {
            ans = smallestM;
        } else if((smallestM + M - cnt) % 2 == 0) {
            ans = smallestM + M;
        }
    }
    cout << ans << "\n";
}
0