結果
問題 | No.2080 Simple Nim Query |
ユーザー | だれ |
提出日時 | 2022-09-25 21:44:12 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 199 ms / 3,000 ms |
コード長 | 6,526 bytes |
コンパイル時間 | 3,606 ms |
コンパイル使用メモリ | 185,736 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-12 07:24:04 |
合計ジャッジ時間 | 5,936 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | AC | 2 ms
6,944 KB |
testcase_03 | AC | 72 ms
6,940 KB |
testcase_04 | AC | 74 ms
6,944 KB |
testcase_05 | AC | 199 ms
6,940 KB |
testcase_06 | AC | 194 ms
6,940 KB |
testcase_07 | AC | 195 ms
6,940 KB |
testcase_08 | AC | 184 ms
6,944 KB |
testcase_09 | AC | 184 ms
6,944 KB |
testcase_10 | AC | 69 ms
6,940 KB |
ソースコード
#include <algorithm> #include <bitset> #include <cassert> #include <cmath> #include <cstdio> #include <fstream> #include <functional> #include <iomanip> #include <iostream> #include <iterator> #include <map> #include <numeric> #include <queue> #include <set> #include <sstream> #include <stack> #include <unordered_set> using namespace std; #if __has_include(<atcoder/all>) #include <atcoder/all> using namespace atcoder; #endif #define GET_MACRO(_1, _2, _3, NAME, ...) NAME #define _rep(i, n) _rep2(i, 0, n) #define _rep2(i, a, b) for(int i = (int)(a); i < (int)(b); i++) #define rep(...) GET_MACRO(__VA_ARGS__, _rep2, _rep)(__VA_ARGS__) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() using i64 = long long; template<class T, class U> bool chmin(T& a, const U& b) { return (b < a) ? (a = b, true) : false; } template<class T, class U> bool chmax(T& a, const U& b) { return (b > a) ? (a = b, true) : false; } inline void YesNo(bool f) { std::cout << (f? "Yes": "No") << std::endl; } template<typename T>istream& operator>>(istream&i,vector<T>&v){rep(j,v.size())i>>v[j];return i;} template<typename T>string join(vector<T>&v){stringstream s;rep(i,v.size())s<<' '<<v[i];return s.str().substr(1);} template<typename T>ostream& operator<<(ostream&o,vector<T>&v){if(v.size())o<<join(v);return o;} template<typename T>string join(vector<vector<T>>&vv){string s="\n";rep(i,vv.size())s+=join(vv[i])+"\n";return s;} template<typename T>ostream& operator<<(ostream&o,vector<vector<T>>&vv){if(vv.size())o<<join(vv);return o;} template<class T, T (*op) (T, T), T (*e)()> struct SegmentTree { private: std::vector<T> data; int _n, size; void update(int k) { data[k] = op(data[k << 1], data[k << 1 | 1]); } public: SegmentTree(int n) : SegmentTree(std::vector<T>(n, e())) {} SegmentTree(const std::vector<T>& v) : size(int(v.size())) { for (_n = 1; _n < size; _n *= 2); data.resize(2 * _n, e()); for (int i = 0; i < size; i++) data[i + _n] = v[i]; for (int i = _n - 1; i > 0; i--) update(i); } void set(int i, const T x) { assert(0 <= i && i < size); i += _n; data[i] = x; while (i > 1) { i >>= 1; update(i); } } void add(int i, const T x) { assert(0 <= i && i < size); i += _n; data[i] += x; while (i > 1) { i >>= 1; update(i); } } T get(int i) { assert(0 <= i && i < size); return data[i + _n]; } T prod(int l, int r) { assert(0 <= l && l <= r && r <= size); T lf = e(), rf = e(); l += _n; r += _n; while(l < r) { if (l & 1) lf = op(lf, data[l++]); if (r & 1) rf = op(data[--r], rf); l >>= 1; r >>= 1; } return op(lf, rf); } T all_prod() const { return data[1]; } template<bool (*f) (T, T)> int min_left(int l, int r, T target) { assert(0 <= l && l <= r && r <= size); l += _n; r += _n; vector<int> lv, rv; while (l < r) { if (l & 1) { lv.push_back(l++); } if (r & 1) { rv.push_back(--r); } l >>= 1; r >>= 1; } while (!rv.empty()) { lv.push_back(rv.back()); rv.pop_back(); } T now = e(); for (auto i: lv) { if (f(op(now, data[i]), target)) { while (true) { if(f(op(now, data[i]), target)) { if (i >= _n) return i - _n; i <<= 1; } else now = op(now, data[i++]); } } else now = op(now, data[i]); } return -1; } template<bool (*f) (T, T)> int max_right(int l, int r, T target) { assert(0 <= l && l <= r && r <= size); l += _n; r += _n; vector<int> lv, rv; while (l < r) { if (l & 1) { lv.push_back(l++); } if (r & 1) { rv.push_back(--r); } l >>= 1; r >>= 1; } while (!lv.empty()) { rv.push_back(lv.back()); lv.pop_back(); } T now = e(); for (auto i: rv) { if (f(op(data[i], now), target)) { while (true) { if(f(op(data[i], now), target)) { if (i >= _n) return i - _n; i <<= 1; i++; } else now = op(data[i--], now); } } else now = op(data[i], now); } return -1; } }; int op(int a, int b) { return max(a, b); } int e(){ return 0; } bool se(int a, int b) { return a > 1; } int main(){ cin.tie(nullptr); ios::sync_with_stdio(false); int n, q; cin >> n >> q; vector<int> a(n); cin >> a; SegmentTree<int, op, e> seg(a); while (q--) { int t, x, y; cin >> t >> x >> y; x--; if (t == 1) { seg.set(x, y); } else { if (seg.prod(x, y) > 1) { auto z = seg.max_right<se>(x, y, 0); assert(z != -1); auto w = y - z + 1; cout << (w & 1? 'S': 'F') << "\n"; } else { cout << ((y - x) & 1? 'F': 'S') << "\n"; } } } }