Submission #493569

#TimeUsernameProblemLanguageResultExecution timeMemory
493569AndreyPavlovBall Machine (BOI13_ballmachine)C++14
100 / 100
383 ms46004 KiB
/* Includes */ #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> /* Using libraries */ using namespace std; using namespace __gnu_pbds; /* Some libraries utils */ template <class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; /* Defines */ #define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define int long long #define ld long double #define vc vector #define pb push_back #define out(a) for (int i: a) cout << i << ' '; #define graph(n, g) for (int i = 0; i < n; ++i) {int u, v; cin >> u >> v; --u; --v; g[u].push_back(v); g[v].push_back(u);} #define eb emplace_back #define pii pair <int, int> #define sz(a) (int) a.size() #define forn(i, n) for(int i = 0; i < n; ++i) /* Constants */ const int inf = 1e15 + 7, mod = 1e9 + 7, maxn = 305, maxc = 27; /* Utils */ class Utils { public: class Modular { private: int n, md; public: Modular (): n(0), md(mod){} Modular (int n): md(mod) { this->n = normalize(n); } Modular (int n, int md): md(md) { this->n = normalize(n); } int normalize (int x) { if (abs(x) >= md) x %= md; if (x < 0) return x + md; return x; } Modular& operator = (int &x) { this->n = normalize(x); return *this; } Modular& operator += (const Modular &b) {return *this = *this + b;} Modular& operator -= (const Modular &b) {return *this = *this - b;} Modular& operator *= (const Modular &b) {return *this = *this * b;} Modular& operator /= (const Modular &b) {return *this = *this / b;} friend const Modular operator + (const Modular &a, const Modular &b) { assert(a & b); return Modular(a.n + b.n, a.md); } friend const Modular operator - (const Modular &a, const Modular &b) { assert(a & b); return Modular(a.n - b.n, a.md); } friend const Modular operator * (const Modular &a, const Modular &b) { assert(a & b); return Modular(a.n * b.n, a.md); } friend const Modular operator / (const Modular &a, const Modular &b) { assert(a & b); return Modular(a.n * Utils::Numbers::inverse(b.n, b.md), a.md); } friend ostream& operator << (ostream &os, const Modular& b) { return os << b.n; } friend istream& operator >> (istream &os, Modular& b) { os >> b.n; b = Modular(b.n, b.md); return os; } bool operator == (const Modular &b) const { return n == b.n; } bool operator != (const Modular &b) const { return !(*this == b); } friend bool operator & (const Modular &a, const Modular &b) { return a.md == b.md; } }; class Numbers { public: using mint = Utils::Modular; int static gcd (int a, int b) { return b == 0 ? a : gcd(b, a % b); } int static lcm (int a, int b) { if (a == 0 && b == 0) return 0; return a / Utils::Numbers::gcd(a, b) * b; } int static gcdex (int a, int b, int &x, int &y) { if (b == 0) { x = 1; y = 0; return a; } int x1, y1; int d = gcdex(b, a % b, x1, y1); x = y1; y = x1 - (a / b) * y1; return d; } int static inverse (int a, int m) { int x, y; int g = Utils::Numbers::gcdex(a, m, x, y); assert(g == 1); return (x % m + m) % m; } mint static bin_pow (mint a, int b, int m) { mint res(1, m); while (b) { if (b & 1) res *= a; a *= a; b >>= 1; } return res; } int static bin_pow (int a, int b, int m) { int res = 1; while (b) { if (b & 1) res = res * a % m; a = a * a % m; b >>= 1; } return res; } int static g (int n) { return n ^ (n >> 1); } int static rev_g (int n) { int f = 0; for (; n; n >>= 1) f ^= n; return f; } int static phi (int n) { int f = n; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { while (n % i == 0) n /= i; f -= f / i; } } if (n > 1) f -= f / n; return f; } }; class Combinatoric { public: using mint = Utils::Modular; int maxn, mod; vc <mint> fact, inv; Combinatoric(int maxn, int mod = 1e9 + 7): maxn(maxn), mod(mod) { fact.resize(maxn + 1, mint(0, mod)); inv.resize(maxn + 1, mint(0, mod)); fact[0] = fact[1] = mint(1, mod); for (int i = 2; i <= maxn; ++i) { fact[i] = fact[i - 1] * mint(i, mod); } inv[maxn] = mint(1, mod) / fact[maxn]; for (int i = maxn; i >= 1; --i) { inv[i - 1] = inv[i] * mint(i, mod); } } mint C (int n, int k) { if (k > n) return 1; return fact[n] * inv[n - k] * inv[k]; } mint F (int n) { return fact[n]; } mint InvF (int n) { return inv[n]; } }; class bitset { private: using T = unsigned long long; T SZ = 6; T base = 1ll << SZ; T mod = base - 1; T n; public: vc <T> t; bitset (T n) { this->n = n; t.resize((n + base - 1) / base); } T operator [](T i) { return t[i >> SZ] & (1 << (i & mod)); } void set (T i, T val) { if ((*this)[i] == val) return; t[i >> SZ] ^= 1 << (i & mod); } }; class Geometric { public: /* Point (and vector) */ class pt { public: ld x, y; int i = -1; pt (ld x = 0, ld y = 0, int i = -1): x(x), y(y), i(i){} pt operator - () const {return pt(-x, -y);} pt operator + (pt &b) const {return pt(x + b.x, y + b.y);} pt operator - (pt &b) const {return pt(x - b.x, y - b.y);} pt& operator = (pt &b) {this->x = b.x, this->y = b.y;} ld operator * (pt &b) const {return x * b.x + y * b.y;} ld operator ^ (pt &b) const {return x * b.y - b.x * y;} bool operator == (pt &b) const {return x == b.x && y == b.y;} bool operator != (pt &b) const {return !(*this == b);} bool operator < (pt &b) const {return x == b.x ? y < b.y : x < b.x;} bool operator <= (pt &b) const {return *this < b || *this == b;} bool operator > (pt &b) const {return !(*this <= b);} bool operator >= (pt &b) const {return *this > b || *this == b;} friend ostream& operator << (ostream &os, pt &a) {return os << a.x << ' ' << a.y;} friend istream& operator >> (istream &os, pt &a) {return os >> a.x >> a.y;} ld operator [](int j) {return j == 0 ? x : y;} ld angle () { if (x == 0 && y == 0) return -1; if (x == 0) return y > 0 ? 90 : 270; ld t = atan(y / x) * (360 ); if (x > 0) return y >= 0 ? t : t + 360; return t + 180; } ld len_sq () {return x * x + y * y;} ld length () {return sqrtl(this->len_sq());} }; using pt = Utils::Geometric::pt; ld orientation (pt a, pt b, pt c) { pt ab = b - a, ac = c - a; ld sa = ab ^ ac; if (sa > 0) return 1; if (sa == 0) return 0; if (sa < 0) return -1; } }; }; using mint = Utils::Modular; using Math = Utils::Numbers; int n, q, logn, root, ti, last; vc <vc <int>> g, p; vc <vc <pii>> to; vc <int> used, tin, deg, cnt, h; int precalc (int u, int t = -1) { for (int i = 1; i < logn; ++i) { p[u][i] = p[p[u][i - 1]][i - 1]; } int ans = inf; for (int v: g[u]) { if (v != t) { h[v] = h[u] + 1; int tmp = precalc(v, u); ans = min(ans, tmp); to[u].pb({tmp, v}); } } sort(to[u].begin(), to[u].end()); ans = min(ans, u); return ans; } void dfs (int u) { tin[u] = ti++; for (auto &[mysor, v]: to[u]) { dfs(v); } } bool cmp (int i, int j) { return tin[i] < tin[j]; } void solve () { cin >> n >> q; ti = 0; logn = __lg(n) + 1; g.resize(n); p.resize(n, vc <int> (logn)); to.resize(n); used.resize(n); tin.resize(n); deg.resize(n); cnt.resize(n); h.resize(n); for (int i = 0; i < n; ++i) { int u; cin >> u; if (u == 0) { root = i; continue; } --u; g[u].pb(i); g[i].pb(u); deg[u]++; p[i][0] = u; } forn (i, logn) p[root][i] = root; precalc(root); auto check = [&](int u) { return !used[u]; }; dfs(root); set <int, decltype(&cmp)> s(cmp); forn (i, n) { if (deg[i] == 0) { s.insert(i); } } while (q--) { int cmd, x; cin >> cmd >> x; if (cmd == 1) { while (x--) { int u = *s.begin(); last = u; int v = p[u][0]; used[u] = 1; if (u != root) { cnt[v]++; if (cnt[v] == deg[v]) { s.insert(v); } } s.erase(u); } cout << last + 1 << '\n'; } else { int c = 0; --x; if (used[root]) { used[root] = 0; s.insert(root); cout << h[x] << '\n'; continue; } for (int l = logn - 1; ~l; --l) { if (!check(p[x][l])) { c += (1ll << l); x = p[x][l]; } } used[x] = 0; if (x != root) { --cnt[p[x][0]]; s.erase(p[x][0]); } s.insert(x); cout << c << '\n'; } } } /* Starting and precalcing */ signed main() { /* freopen("input.txt","r",stdin);freopen("output.txt","w",stdout); */ fast; int t = 1; // cin >> t; while (t--) solve(); return 0; }

Compilation message (stderr)

ballmachine.cpp: In member function 'Utils::Geometric::pt& Utils::Geometric::pt::operator=(Utils::Geometric::pt&)':
ballmachine.cpp:220:66: warning: no return statement in function returning non-void [-Wreturn-type]
  220 |             pt& operator = (pt &b) {this->x = b.x, this->y = b.y;}
      |                                                                  ^
      |                                                                  return *this;
ballmachine.cpp: In function 'void dfs(long long int)':
ballmachine.cpp:282:16: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  282 |     for (auto &[mysor, v]: to[u]) {
      |                ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...