結果
問題 | No.1558 Derby Live |
ユーザー |
![]() |
提出日時 | 2021-06-27 13:42:13 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 185 ms / 2,000 ms |
コード長 | 3,999 bytes |
コンパイル時間 | 1,767 ms |
コンパイル使用メモリ | 176,948 KB |
実行使用メモリ | 5,632 KB |
最終ジャッジ日時 | 2024-06-25 11:11:09 |
合計ジャッジ時間 | 8,945 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
ソースコード
/*** @FileName a.cpp* @Author kanpurin* @Created 2021.06.27 13:42:05**/#include "bits/stdc++.h"using namespace std;typedef long long ll;template < class Monoid >struct SegmentTree {private:using Func = std::function< Monoid(Monoid, Monoid) >;Func F;Monoid UNITY;int n;std::vector< Monoid > node;int _binary_search(int a, int b, const std::function<bool(Monoid)> &f, Monoid &s, int k = 0, int l = 0, int r = -1) {if (r < 0) r = n;if (r <= a || b <= l) return n;if (a <= l && r <= b && !f(F(s,node[k]))) {s = F(s,node[k]);return n;}if (l == r - 1) {s = F(s,node[k]); return l;}int ret = _binary_search(a, b, f, s, 2 * k + 1, l, (r - l) / 2 + l);return ret != n ? ret : _binary_search(a, b, f, s, 2 * k + 2, (r - l) / 2 + l, r);}public:SegmentTree() {}SegmentTree(const std::vector< Monoid > &v, const Func f, const Monoid &unity) {F = f;UNITY = unity;int sz = v.size();n = 1;while (n < sz) n <<= 1;node.resize(n * 2 - 1, UNITY);for (int i = 0; i < sz; i++) node[i + n - 1] = v[i];build();}SegmentTree(int m, const Monoid &val, const Func f, const Monoid &unity) {F = f;UNITY = unity;n = 1;while (n < m) n <<= 1;node.resize(n * 2 - 1, UNITY);if (val != UNITY) {for (int i = 0; i < m; i++) node[i + n - 1] = val;build();}}void set(int k, const Monoid &x) {node[n + k - 1] = x;}void build() {for (int i = n - 2; i >= 0; i--) node[i] = F(node[2 * i + 1], node[2 * i + 2]);}void update_query(int x, const Monoid &val) {if (x >= n || x < 0) return;x += n - 1;node[x] = val;while (x > 0) {x = (x - 1) >> 1;node[x] = F(node[2 * x + 1], node[2 * x + 2]);}}Monoid get_query(int l, int r) {Monoid L = UNITY, R = UNITY;if (l < 0) l = 0;if (r < 0) return UNITY;if (l >= n) return UNITY;if (r >= n) r = n;for (l += n, r += n; l < r; l >>= 1, r >>= 1) {if (l & 1) L = F(L, node[l++ - 1]);if (r & 1) R = F(node[--r - 1], R);}return F(L, R);}int binary_search(int l, int r, const std::function<bool(Monoid)> &f) {Monoid s = UNITY;int ret = _binary_search(l,r,f,s);return ret != n ? ret : -1;}Monoid operator[](int x) const {return node[n + x - 1];}int size() {return n;}void print() {for (int i = 0; i < n; i++) {std::cout << i << "\t: " << node[n + i - 1] << std::endl;}}};int main() {int n,m,q;cin >> n >> m >> q;array<int,18> e;iota(e.begin(), e.end(),1);SegmentTree<array<int,18>> seg(m,e,[](array<int,18> a,array<int,18> b){array<int,18> ret;for (int i = 0; i < 18; i++) ret[i] = b[a[i]-1];return ret;},e);while(q--) {int t;cin >> t;if (t == 1) {int d;cin >> d;array<int,18> p = e;for (int i = 0; i < n; i++) cin >> p[i];seg.update_query(d-1,p);}else if (t == 2) {int s;cin >> s;auto g = seg.get_query(0,s);array<int,18> ans;for (int i = 0; i < n; i++) {ans[g[i]-1] = i+1;}for (int i = 0; i < n; i++) {cout << ans[i] << " ";}cout << endl;}else {int l,r;cin >> l >> r;int ans = 0;auto g = seg.get_query(l-1,r);for (int i = 0; i < n; i++) {ans += abs(g[i]-i-1);}cout << ans << endl;}}return 0;}