結果

問題 No.2382 Amidakuji M
ユーザー CoCo_Japan_pan
提出日時 2023-07-14 23:26:38
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
AC  
実行時間 49 ms / 2,000 ms
コード長 4,351 bytes
コンパイル時間 8,977 ms
コンパイル使用メモリ 277,500 KB
最終ジャッジ日時 2025-02-15 14:47:04
ジャッジサーバーID
(参考情報)
judge2 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 19
権限があれば一括ダウンロードができます

ソースコード

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) xf
// 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);
// logNlazy
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;
}
vec<int> numToID(N);
for(int i = 0; i < N; i++) {
numToID[P[i]] = i;
}
DualSegTree<rangeAddOne> dual(N, 0);
//
ll cnt = 0;
for(int i = 0; i < N; i++) {
cnt += dual.get(numToID[i]) + numToID[i] - i;
dual.apply(0, numToID[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";
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0