結果
問題 | No.2382 Amidakuji M |
ユーザー | umimel |
提出日時 | 2023-07-14 22:11:05 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 83 ms / 2,000 ms |
コード長 | 3,284 bytes |
コンパイル時間 | 1,749 ms |
コンパイル使用メモリ | 173,520 KB |
実行使用メモリ | 8,960 KB |
最終ジャッジ日時 | 2024-09-16 07:14:46 |
合計ジャッジ時間 | 3,336 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 19 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; using pll = pair<ll, ll>; #define drep(i, cc, n) for (ll i = (cc); i <= (n); ++i) #define rep(i, n) drep(i, 0, n - 1) #define all(a) (a).begin(), (a).end() #define pb push_back #define fi first #define se second mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count()); const ll MOD1000000007 = 1000000007; const ll MOD998244353 = 998244353; const ll MOD[3] = {999727999, 1070777777, 1000000007}; const ll LINF = 1LL << 60; const int IINF = 1 << 30 - 1; template<typename T> struct Edge{ int to; T w; Edge(int to_, T w_=1){ to = to_; w=w_; } }; template<typename T> using Tree = vector<vector<Edge<T>>>; template<typename T> using Graph = vector<vector<Edge<T>>>; /* 容量&重み付きエッジ for Dinic */ template<typename T> struct REdge{ int to; T cap; T cost; int rev; REdge(int to_, T cap_, T cost_=1){ to = to_; cap = cap_; cost = cost_; } REdge(int to_, T cap_, T cost_, int rev_){ to = to_; cap = cap_; cost = cost_; rev = rev_; } }; /* 残余グラフ for Dinic */ template<typename T> using RGraph = vector<vector<REdge<T>>>; struct UnionFind{ vector<ll> parent; vector<ll> sizes; UnionFind(ll N) : parent(N), sizes(N, 1){ rep(i, N) parent[i] = i; } ll root(ll x){ if (parent[x] == x) return x; return parent[x] = root(parent[x]); } void unite(ll x, ll y){ ll rx = root(x); ll ry = root(y); if (rx == ry) return; if (sizes[rx] < sizes[ry]) swap(rx, ry); sizes[rx] += sizes[ry]; parent[ry] = rx; } bool same(ll x, ll y){ ll rx = root(x); ll ry = root(y); return rx == ry; } ll size(ll x){ return sizes[root(x)]; } }; struct SegmentTree{ ll n; vector<ll> dat; SegmentTree(ll n_){ n = 1; while(n < n_) n*=2; dat.resize(2*n, 0); } void update(ll k, ll a){ k += n-1; dat[k] += a; while(k > 0){ k = (k-1)/2; dat[k] = dat[2*k+1]+dat[2*k+2]; } } // the minimun element of [a, b) ll query(ll a, ll b){return query_sub(a, b, 0, 0, n);} ll query_sub(ll a, ll b, ll k, ll l, ll r){ if(r <= a || b <= l){ return 0; }else if(a <= l && r <= b){ return dat[k]; }else{ ll vl = query_sub(a, b, 2*k+1, l, (l+r)/2); ll vr = query_sub(a, b, 2*k+2, (l+r)/2, r); return vl+vr; } } }; int main(){ cin.tie(nullptr); ios::sync_with_stdio(false); ll n, m; cin >> n >> m; vector<ll> p(n); rep(i, n){ cin >> p[i]; p[i]--; } ll cnt = 0; SegmentTree seg(n); rep(i, n){ cnt += seg.query(p[i]+1, n); seg.update(p[i], 1); } if(m%2==0){ if(cnt%2==1){ cout << -1 << endl; }else{ cout << cnt + (m-cnt%m)%m << endl; } }else{ ll l = cnt + (m-cnt%m)%m; if((l-cnt)%2==0){ cout << l << endl; }else{ cout << l+m << endl; } } }