結果
問題 | No.2325 Skill Tree |
ユーザー | Kyo_s_s |
提出日時 | 2023-05-28 14:07:53 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 154 ms / 3,000 ms |
コード長 | 10,769 bytes |
コンパイル時間 | 1,809 ms |
コンパイル使用メモリ | 178,832 KB |
実行使用メモリ | 8,960 KB |
最終ジャッジ日時 | 2024-06-08 04:45:44 |
合計ジャッジ時間 | 8,530 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 1 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 36 ms
5,376 KB |
testcase_08 | AC | 32 ms
5,376 KB |
testcase_09 | AC | 43 ms
5,376 KB |
testcase_10 | AC | 45 ms
6,528 KB |
testcase_11 | AC | 47 ms
5,504 KB |
testcase_12 | AC | 92 ms
7,936 KB |
testcase_13 | AC | 94 ms
7,936 KB |
testcase_14 | AC | 97 ms
7,936 KB |
testcase_15 | AC | 94 ms
7,808 KB |
testcase_16 | AC | 91 ms
7,936 KB |
testcase_17 | AC | 90 ms
7,936 KB |
testcase_18 | AC | 88 ms
7,936 KB |
testcase_19 | AC | 87 ms
7,936 KB |
testcase_20 | AC | 87 ms
7,808 KB |
testcase_21 | AC | 86 ms
7,808 KB |
testcase_22 | AC | 93 ms
7,936 KB |
testcase_23 | AC | 95 ms
7,936 KB |
testcase_24 | AC | 90 ms
8,064 KB |
testcase_25 | AC | 93 ms
7,936 KB |
testcase_26 | AC | 93 ms
7,936 KB |
testcase_27 | AC | 147 ms
8,960 KB |
testcase_28 | AC | 149 ms
8,960 KB |
testcase_29 | AC | 138 ms
8,960 KB |
testcase_30 | AC | 143 ms
8,704 KB |
testcase_31 | AC | 145 ms
8,832 KB |
testcase_32 | AC | 116 ms
8,576 KB |
testcase_33 | AC | 130 ms
8,832 KB |
testcase_34 | AC | 133 ms
8,960 KB |
testcase_35 | AC | 148 ms
8,576 KB |
testcase_36 | AC | 135 ms
8,448 KB |
testcase_37 | AC | 154 ms
8,960 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; // #include <atcoder/all> // using namespace atcoder; /* alias */ using ull = unsigned long long; using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; using vi = vector<int>; using vll = vector<long long>; using vd = vector<double>; using vs = vector<string>; using vb = vector<bool>; using vpii = vector<pair<int, int>>; using vpll = vector<pair<ll, ll>>; using vvi = vector<vector<int>>; using vvll = vector<vector<long long>>; using vvd = vector<vector<double>>; using vvs = vector<vector<string>>; using vvb = vector<vector<bool>>; template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>; /* define */ #define MOD 998244353 // #define MOD 1000000007 #define INF (1LL << 60) #define elif else if #define pb push_back #define pf push_front #define fi first #define se second #define all(obj) (obj).begin(), (obj).end() #define YESNO(bool) cout << (bool ? "YES\n" : "NO\n") #define YesNo(bool) cout << (bool ? "Yes\n" : "No\n") #define yesno(bool) cout << (bool ? "yes\n" : "no\n") template<class T> bool chmax(T &a, const T &b) {if(a<b){ a=b; return 1;} return 0;} template<class T> bool chmin(T &a, const T &b) {if(b<a){ a=b; return 1;} return 0;} #define debug(x) cerr << #x << ":" << x << "\n"; /* REP macro */ #define reps(i, a, n) for(ll i = (a); i < (n); i++) #define rep(i, n) reps(i, 0, (n)) #define rrep(i, n) reps(i, 1, (n + 1)) #define repd(i, n) for(ll i = (n - 1); i >= 0; i--) #define rrepd(i, n) for(ll i = (n); i >= 1; i--) #define fore(i, a) for(auto &i: a) /* vector */ template<class T> T vmax(vector<T> &array){ T ret = array[0]; for(T a: array) chmax(ret, a); return ret; } template<class T> T vmin(vector<T> &array){ T ret = array[0]; for(T a: array) chmin(ret, a); return ret; } template<class T> T sum(vector<T> &array){ T ret = 0; for(T a:array) ret += a; return ret; } template<class T> void list_set(vector<T> &array){ sort(all(array)); array.erase(unique(all(array)),array.end()); } template<class T> int bisect_left(vector<T> &array, T key){ return lower_bound(all(array),key) - array.begin(); } template<class T> int bisect_right(vector<T> &array, T key){ return upper_bound(all(array),key) - array.begin(); } /* string */ ll string_to_ll(string n){ ll ret = 0, k = 1; while(n.length() > 0){ ret += k * (n.back() - '0'); n.pop_back(); k *= 10; } return ret; } string ll_to_string(ll n){ string ret = ""; while(n > 0){ ret.pb((n % 10) + '0'); n /= 10; } reverse(all(ret)); return ret; } struct popopo{ popopo(){ cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(15); }; } popopoppo; // n = 1,...,N に対して、n % A < B を満たすものの数 ll Count_of_n_mod_A_less_than_B(ll N, ll A, ll B){ return N / A * min(A, B) + min(N % A, B - 1); } /* IN/OUT */ int scan() { return getchar(); } void scan(int &a) { cin >> a; } void scan(long long &a) { cin >> a; } void scan(char &a) { cin >> a; } void scan(double &a) { cin >> a; } void scan(string &a) { cin >> a; } template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); } template <class T> void scan(vector<T> &); template <class T> void scan(vector<T> &a) { for(auto &i : a) scan(i); } void IN(){} template<class Head, class... Tail> void IN(Head& head, Tail &...tail){ scan(head); IN(tail...); } #define INT(...) int __VA_ARGS__; IN(__VA_ARGS__) #define LL(...) ll __VA_ARGS__; IN(__VA_ARGS__) #define STR(...) string __VA_ARGS__; IN(__VA_ARGS__) #define VEC(type, name, size) vector<type> name(size); IN(name) #define VECS(type, name, size) vector<type> name(size + 1); for(int i = 1; i <= size; i++) scan(name[i]) void OUT(){ cout << "\n"; } template<class T> void output(T a){ cout << a; } template<class T> void output(vector<T> v){ for(int i = 0; i < v.size(); i++) cout << v[i] << (i == v.size() - 1 ? "" : " "); } template<class Head, class... Tail> void OUT(const Head &head, const Tail &...tail) { output(head); if(sizeof...(tail)) cout << " "; OUT(tail...); } void FLASH(){ cout << endl; } template<class Head, class... Tail> void FLASH(const Head &head, const Tail &...tail) { output(head); if(sizeof...(tail)) cout << " "; FLASH(tail...); } template<class T> struct CumulativeSum { int n; vector<T> data; bool builded = false; CumulativeSum(int n) : n(n), data(n + 1) {} CumulativeSum(const vector<T> &v) : n(v.size()), data(n + 1) { for (int i = 0; i < n; i++) { data[i + 1] = v[i]; } } void build() { for (int i = 0; i < n; i++) { data[i + 1] += data[i]; } builded = true; } T sum(int r) { if (!builded) build(); assert(0 <= r && r <= n); return data[r]; } T sum(int l, int r) { assert(0 <= l && l <= r && r <= n); return sum(r) - sum(l); } }; template <class S, S (*op)(S, S), S (*e)()> class dynamic_segtree { public: dynamic_segtree(size_t n) : n(n), root(nullptr) {} void set(size_t p, S x) { assert(p < n); set(root, 0, n, p, x); } S get(size_t p) const { assert(p < n); return get(root, 0, n, p); } S prod(size_t l, size_t r) const { assert(l <= r && r <= n); return prod(root, 0, n, l, r); } S all_prod() const { return root ? root->product : e(); } void reset(size_t l, size_t r) { assert(l <= r && r <= n); return reset(root, 0, n, l, r); } template <bool (*f)(S)> size_t max_right(size_t l) const { return max_right(l, [](S x) { return f(x); }); } template <class F> size_t max_right(size_t l, const F& f) const { assert(l <= n); S product = e(); assert(f(product)); return max_right(root, 0, n, l, f, product); } template <bool (*f)(S)> size_t min_left(size_t r) const { return min_left(r, [](S x) { return f(x); }); } template <class F> size_t min_left(size_t r, const F& f) const { assert(r <= n); S product = e(); assert(f(product)); return min_left(root, 0, n, r, f, product); } private: struct node; using node_ptr = std::unique_ptr<node>; struct node { size_t index; S value, product; node_ptr left, right; node(size_t index, S value) : index(index), value(value), product(value), left(nullptr), right(nullptr) {} void update() { product = op(op(left ? left->product : e(), value), right ? right->product : e()); } }; const size_t n; node_ptr root; void set(node_ptr& t, size_t a, size_t b, size_t p, S x) const { if (!t) { t = std::make_unique<node>(p, x); return; } if (t->index == p) { t->value = x; t->update(); return; } size_t c = (a + b) >> 1; if (p < c) { if (t->index < p) std::swap(t->index, p), std::swap(t->value, x); set(t->left, a, c, p, x); } else { if (p < t->index) std::swap(p, t->index), std::swap(x, t->value); set(t->right, c, b, p, x); } t->update(); } S get(const node_ptr& t, size_t a, size_t b, size_t p) const { if (!t) return e(); if (t->index == p) return t->value; size_t c = (a + b) >> 1; if (p < c) return get(t->left, a, c, p); else return get(t->right, c, b, p); } S prod(const node_ptr& t, size_t a, size_t b, size_t l, size_t r) const { if (!t || b <= l || r <= a) return e(); if (l <= a && b <= r) return t->product; size_t c = (a + b) >> 1; S result = prod(t->left, a, c, l, r); if (l <= t->index && t->index < r) result = op(result, t->value); return op(result, prod(t->right, c, b, l, r)); } void reset(node_ptr& t, size_t a, size_t b, size_t l, size_t r) const { if (!t || b <= l || r <= a) return; if (l <= a && b <= r) { t.reset(); return; } size_t c = (a + b) >> 1; reset(t->left, a, c, l, r); reset(t->right, c, b, l, r); t->update(); } template <class F> size_t max_right(const node_ptr& t, size_t a, size_t b, size_t l, const F& f, S& product) const { if (!t || b <= l) return n; if (f(op(product, t->product))) { product = op(product, t->product); return n; } size_t c = (a + b) >> 1; size_t result = max_right(t->left, a, c, l, f, product); if (result != n) return result; if (l <= t->index) { product = op(product, t->value); if (!f(product)) return t->index; } return max_right(t->right, c, b, l, f, product); } template <class F> size_t min_left(const node_ptr& t, size_t a, size_t b, size_t r, const F& f, S& product) const { if (!t || r <= a) return 0; if (f(op(t->product, product))) { product = op(t->product, product); return 0; } size_t c = (a + b) >> 1; size_t result = min_left(t->right, c, b, r, f, product); if (result != 0) return result; if (t->index < r) { product = op(t->value, product); if (!f(product)) return t->index + 1; } return min_left(t->left, a, c, r, f, product); } }; using S = ll; S op(S a, S b) { return a + b; } S e() { return 0; } int main() { LL(N); vll L(N), A(N); rep(i, N - 1) { LL(l, a); L[i + 1] = l; A[i + 1] = a - 1; } vll memo(N, -1); memo[0] = 1; // memo[i] := 技 i を覚えるのに最小のレベル auto lev = [&](auto &&self, ll i) -> ll { if (memo[i] == -2) { memo[i] = INF; return INF; } if (memo[i] != -1) return memo[i]; memo[i] = -2; ll v = self(self, A[i]); memo[i] = max(v, L[i]); return memo[i]; }; dynamic_segtree<S, op, e> seg(1000000100); rep(i, N) { ll v = lev(lev, i); if (v == INF) { continue; } ll now = seg.get(v); seg.set(v, now + 1); } LL(Q); while (Q--) { LL(t); if (t == 1) { LL(x); ll ans = seg.prod(0, x + 1); OUT(ans); } else { LL(y); y--; ll v = lev(lev, y); if (v == INF) { v = -1; } OUT(v); } } }