結果
問題 | No.1226 I hate Robot Arms |
ユーザー | risujiroh |
提出日時 | 2020-09-11 22:19:28 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 812 ms / 2,000 ms |
コード長 | 6,175 bytes |
コンパイル時間 | 3,407 ms |
コンパイル使用メモリ | 288,240 KB |
実行使用メモリ | 16,112 KB |
最終ジャッジ日時 | 2024-06-10 10:20:32 |
合計ジャッジ時間 | 22,407 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | AC | 242 ms
6,940 KB |
testcase_03 | AC | 295 ms
6,940 KB |
testcase_04 | AC | 327 ms
12,904 KB |
testcase_05 | AC | 292 ms
15,508 KB |
testcase_06 | AC | 810 ms
14,780 KB |
testcase_07 | AC | 228 ms
6,940 KB |
testcase_08 | AC | 74 ms
13,064 KB |
testcase_09 | AC | 529 ms
6,940 KB |
testcase_10 | AC | 60 ms
6,940 KB |
testcase_11 | AC | 357 ms
12,440 KB |
testcase_12 | AC | 197 ms
8,320 KB |
testcase_13 | AC | 147 ms
15,616 KB |
testcase_14 | AC | 674 ms
6,940 KB |
testcase_15 | AC | 42 ms
14,236 KB |
testcase_16 | AC | 789 ms
15,724 KB |
testcase_17 | AC | 210 ms
7,424 KB |
testcase_18 | AC | 139 ms
7,680 KB |
testcase_19 | AC | 365 ms
13,824 KB |
testcase_20 | AC | 356 ms
12,884 KB |
testcase_21 | AC | 485 ms
11,832 KB |
testcase_22 | AC | 796 ms
16,068 KB |
testcase_23 | AC | 810 ms
16,104 KB |
testcase_24 | AC | 807 ms
16,112 KB |
testcase_25 | AC | 812 ms
15,948 KB |
testcase_26 | AC | 811 ms
15,972 KB |
testcase_27 | AC | 783 ms
15,880 KB |
testcase_28 | AC | 793 ms
15,876 KB |
testcase_29 | AC | 781 ms
15,940 KB |
ソースコード
#pragma GCC optimize("Ofast") #include <bits/extc++.h> struct segment_tree_base { virtual int size() const = 0; protected: template <class F> void forward(int l, int r, F f) const { int h = h1(l += size() - 1, r += size()); for (int s = 0; s < h; ++s) if (int i = l >> s; ~i & 1) f(i + 1); for (int s = h; s--;) if (int i = r >> s; i & 1) f(i - 1); } template <class F> void forward(int l, int r, F f) { const_cast<const segment_tree_base*>(this)->forward(l, r, f); } template <class F> void backward(int l, int r, F f) const { int h = h1(l += size() - 1, r += size()); for (int s = 0; s < h; ++s) if (int i = r >> s; i & 1) f(i - 1); for (int s = h; s--;) if (int i = l >> s; ~i & 1) f(i + 1); } template <class F> void backward(int l, int r, F f) { const_cast<const segment_tree_base*>(this)->backward(l, r, f); } template <class F> void downward(int l, int r, F f) const { if (l == r or (l == 0 and r == size())) return; int h = h2(l += size(), r += size()); for (int s = std::__lg(l); s > h; --s) f(l >> s); for (int s = h; s > __builtin_ctz(l); --s) f(l >> s); for (int s = h; s > __builtin_ctz(r); --s) f(r >> s); } template <class F> void downward(int l, int r, F f) { const_cast<const segment_tree_base*>(this)->downward(l, r, f); } template <class F> void upward(int l, int r, F f) const { if (l == r or (l == 0 and r == size())) return; int h = h2(l += size(), r += size()); for (int s = __builtin_ctz(r); s++ < h;) f(r >> s); for (int s = __builtin_ctz(l); s++ < h;) f(l >> s); for (int s = h; s++ < std::__lg(l);) f(l >> s); } template <class F> void upward(int l, int r, F f) { const_cast<const segment_tree_base*>(this)->upward(l, r, f); } private: static int h1(int l, int r) { for (int h = 0;; ++h) if ((r >> h) - (l >> h) == 1) return h; } static int h2(int l, int r) { l <<= std::__lg(l) < std::__lg(r); return std::__lg(l ^ r); } }; template <class T, class Action> struct lazy_segment_tree : segment_tree_base { lazy_segment_tree() {} template <class Generator> lazy_segment_tree(int n, Generator gen) : tree(2 * n), lazy(n) { for (int i = 0; i < n; ++i) tree[n + i] = gen(i); for (int i = n; i-- > 1;) pull(i); } int size() const override { return std::size(lazy); } T fold(int l, int r) { assert(0 <= l), assert(l <= r), assert(r <= size()); downward(l, r, [&](int i) { push(i); }); T res{}; forward(l, r, [&](int i) { res = res * tree[i]; }); return res; } T get(int i) { assert(0 <= i), assert(i < size()); return fold(i, i + 1); } T fold_all_rotated() const { return size() ? tree[1] : T{}; } template <class Function> void update(int i, Function func) { assert(0 <= i), assert(i < size()); downward(i, i + 1, [&](int j) { push(j); }); tree[size() + i] = func(tree[size() + i]); upward(i, i + 1, [&](int j) { pull(j); }); } void act(int l, int r, const Action& f) { assert(0 <= l), assert(l <= r), assert(r <= size()); downward(l, r, [&](int i) { push(i); }); forward(l, r, [&](int i) { apply(i, f); }); upward(l, r, [&](int i) { pull(i); }); } template <class Predicate> int forward_search(int l, int r, Predicate pred) { assert(0 <= l), assert(l <= r), assert(r <= size()); downward(l, r, [&](int i) { push(i); }); T a{}; assert(pred(a)); int res = r; forward(l, r, [&](int i) { if (res < r) return; if (T na = a * tree[i]; pred(na)) { a = na; return; } while (i < size()) { push(i); if (T na = a * tree[i *= 2]; pred(na)) a = na, ++i; } res = i - size(); }); return res; } template <class Predicate> int backward_search(int l, int r, Predicate pred) { assert(0 <= l), assert(l <= r), assert(r <= size()); downward(l, r, [&](int i) { push(i); }); T a{}; assert(pred(a)); int res = l - 1; backward(l, r, [&](int i) { if (res >= l) return; if (T na = a * tree[i]; pred(na)) { a = na; return; } while (i < size()) { push(i); if (T na = a * tree[i = 2 * i + 1]; pred(na)) a = na, --i; } res = i - size(); }); return res; } private: std::vector<T> tree; std::vector<Action> lazy; void apply(int i, const Action& f) { tree[i] = f(tree[i]); if (i < size()) lazy[i] = lazy[i] * f; } void push(int i) { apply(2 * i, lazy[i]), apply(2 * i + 1, lazy[i]); lazy[i] = Action{}; } void pull(int i) { tree[i] = tree[2 * i] * tree[2 * i + 1]; } }; using num = std::complex<long double>; struct node { num z; friend node operator*(const node& a, const node& b) { return {a.z + b.z}; } }; struct action { num a = 1, b; node operator()(const node& x) const { return {x.z * a + b}; } friend action operator*(const action& f, const action& g) { return {f.a * g.a, f.b * g.a + g.b}; } }; int main() { using namespace std; cin.tie(nullptr)->sync_with_stdio(false); cout << fixed << setprecision(10); int n, q; cin >> n >> q; lazy_segment_tree<node, action> seg(n, [](int i) -> node { return {i + 1}; }); auto get_len = [&](int i) { num d = seg.get(i).z - (i ? seg.get(i - 1).z : 0); return abs(d); }; auto get_arg = [&](int i) -> num::value_type { if (i == -1) return 0; num d = seg.get(i).z - (i ? seg.get(i - 1).z : 0); return arg(d); }; while (q--) { int t, i; cin >> t >> i; --i; if (t == 0) { num::value_type x; cin >> x; x /= 180; x *= acos(num::value_type(-1)); num off = i ? seg.get(i - 1).z : 0; auto th = get_arg(i - 1) + x - get_arg(i); seg.act(i, n, {1, -off}); seg.act(i, n, {polar(num::value_type(1), th), 0}); seg.act(i, n, {1, +off}); } else if (t == 1) { int x; cin >> x; seg.act(i, n, {1, polar(x - get_len(i), get_arg(i))}); } else if (t == 2) { auto z = seg.get(i).z; cout << real(z) << ' ' << imag(z) << '\n'; } else assert(false); } }