cp-documentation

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub zawa-tin/cp-documentation

:heavy_check_mark: Test/CF/CF316-D.test.cpp

Depends on

Code

#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_A"

#include "../../Src/Template/IOSetting.hpp"
#include "../../Src/Graph/Tree/Sack.hpp"

#include <iostream>
#include <utility>
#include <vector>

/*
 * Codeforces Round 316 (Div. 2) - D Tree Requests
 * https://codeforces.com/contest/570/submission/245736854
 */


using namespace zawa;

void solve() {
    SetFastIO();
    int n, q; std::cin >> n >> q;
    Sack sack(n);
    std::vector<int> dep(n);
    for (int i{1} ; i < n ; i++) {
        int p; std::cin >> p;
        sack.addEdge(p - 1, i);
        dep[i] = dep[p - 1] + 1;
    }
    std::string s; std::cin >> s;
    std::vector dat(n, std::vector<std::pair<int, int>>{});
    for (int i{} ; i < q ; i++) {
        int v, h; std::cin >> v >> h;
        v--; h--;
        dat[v].emplace_back(h, i);
    }

    std::vector<bool> ans(q);
    std::vector<std::array<bool, 26>> parity(n);
    for (int i{} ; i < n ; i++) parity[i].fill(false);
    std::vector<int> odd(n);
    auto add{[&](int v) -> void {
        odd[dep[v]] += (parity[dep[v]][s[v] - 'a'] ? -1 : 1);
        parity[dep[v]][s[v] - 'a'] ^= 1;
    }};
    auto del{[&](int v) -> void {
        odd[dep[v]] += (parity[dep[v]][s[v] - 'a'] ? -1 : 1);
        parity[dep[v]][s[v] - 'a'] ^= 1;
    }};
    auto query{[&](int v) -> void {
        for (auto [h, i] : dat[v]) {
            if (h >= n) ans[i] = true;
            else ans[i] = odd[h] <= 1;
        }
    }};
    auto reset{[](){}};
    sack.execute(0, add, del, query, reset);
    for (int i{} ; i < q ; i++) {
        std::cout << (ans[i] ? "Yes" : "No") << '\n';
    }
}

int main() {
#ifdef ONLINE_JUDGE
    solve();
#else
    std::cout << "Hello World" << '\n';
#endif
}
#line 1 "Test/CF/CF316-D.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_A"

#line 2 "Src/Template/IOSetting.hpp"

#line 2 "Src/Template/TypeAlias.hpp"

#include <cstdint>
#include <cstddef>

namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa
#line 4 "Src/Template/IOSetting.hpp"

#include <iostream>
#include <iomanip>

namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
#line 2 "Src/Graph/Tree/Sack.hpp"

#line 4 "Src/Graph/Tree/Sack.hpp"

#include <cassert>
#include <utility>
#include <vector>

namespace zawa {

class Sack {
private:    
    static constexpr u32 INVALID{static_cast<u32>(-1)};
    usize n_{};
    std::vector<std::vector<u32>> g_;
    std::vector<u32> sz_, euler_, L_, R_;

    u32 dfsHLD(u32 v, u32 p) {
        sz_[v] = 1;
        usize m{g_[v].size()};
        usize max{};
        if (m > 1u and g_[v][0] == p) std::swap(g_[v][0], g_[v][1]);
        for (u32 i{} ; i < m ; i++) if (g_[v][i] != p) {
            sz_[v] += dfsHLD(g_[v][i], v);
            if (max < sz_[g_[v][i]]) {
                max = sz_[g_[v][i]];
                if (i) std::swap(g_[v][0], g_[v][i]);
            }
        }
        return sz_[v];
    }

    void dfsEuler(u32 v, u32 p, u32& t) {
        euler_[t] = v;
        L_[v] = t++;
        for (auto x : g_[v]) if (x != p) {
            dfsEuler(x, v, t);
        }
        R_[v] = t;
    }

public:
    constexpr usize size() const noexcept {
        return n_;
    }

    Sack() = default;
    Sack(u32 n) 
        : n_{n}, g_(n), sz_(n), euler_(n), L_(n), R_(n) {
        assert(n);
        g_.shrink_to_fit();
        sz_.shrink_to_fit();
        euler_.shrink_to_fit();
        L_.shrink_to_fit();
        R_.shrink_to_fit();
    }
    void addEdge(u32 u, u32 v) {
        assert(u < size());
        assert(v < size());
        g_[u].emplace_back(v);
        g_[v].emplace_back(u);
    }

    const std::vector<u32>& operator[](u32 v) const noexcept {
        assert(v < size());
        return g_[v];
    }

    template <class ADD, class DEL, class QUERY, class RESET>
    u32 execute(u32 root, const ADD& add, const DEL& del, const QUERY& query, const RESET& reset) {
        dfsHLD(root, INVALID);
        u32 t{};
        dfsEuler(root, INVALID, t);
        
        auto sack{[&](auto dfs, u32 v, u32 p, bool keep) -> void {
            usize m{g_[v].size()};
            for (u32 i{1} ; i < m ; i++) if (g_[v][i] != p) {
                dfs(dfs, g_[v][i], v, false);
            }
            if (sz_[v] > 1u) dfs(dfs, g_[v][0], v, true);
            if (sz_[v] > 1u) {
                for (u32 i{R_[g_[v][0]]} ; i < R_[v] ; i++) {
                    add(euler_[i]);
                }
            }
            add(v);
            query(v);
            if (!keep) {
                for (u32 i{L_[v]} ; i < R_[v] ; i++) {
                    del(euler_[i]);
                }
                reset();
            }
        }};
        sack(sack, root, INVALID, false);

        return sz_[root];
    }
};

} // namespace zawa
#line 5 "Test/CF/CF316-D.test.cpp"

#line 9 "Test/CF/CF316-D.test.cpp"

/*
 * Codeforces Round 316 (Div. 2) - D Tree Requests
 * https://codeforces.com/contest/570/submission/245736854
 */


using namespace zawa;

void solve() {
    SetFastIO();
    int n, q; std::cin >> n >> q;
    Sack sack(n);
    std::vector<int> dep(n);
    for (int i{1} ; i < n ; i++) {
        int p; std::cin >> p;
        sack.addEdge(p - 1, i);
        dep[i] = dep[p - 1] + 1;
    }
    std::string s; std::cin >> s;
    std::vector dat(n, std::vector<std::pair<int, int>>{});
    for (int i{} ; i < q ; i++) {
        int v, h; std::cin >> v >> h;
        v--; h--;
        dat[v].emplace_back(h, i);
    }

    std::vector<bool> ans(q);
    std::vector<std::array<bool, 26>> parity(n);
    for (int i{} ; i < n ; i++) parity[i].fill(false);
    std::vector<int> odd(n);
    auto add{[&](int v) -> void {
        odd[dep[v]] += (parity[dep[v]][s[v] - 'a'] ? -1 : 1);
        parity[dep[v]][s[v] - 'a'] ^= 1;
    }};
    auto del{[&](int v) -> void {
        odd[dep[v]] += (parity[dep[v]][s[v] - 'a'] ? -1 : 1);
        parity[dep[v]][s[v] - 'a'] ^= 1;
    }};
    auto query{[&](int v) -> void {
        for (auto [h, i] : dat[v]) {
            if (h >= n) ans[i] = true;
            else ans[i] = odd[h] <= 1;
        }
    }};
    auto reset{[](){}};
    sack.execute(0, add, del, query, reset);
    for (int i{} ; i < q ; i++) {
        std::cout << (ans[i] ? "Yes" : "No") << '\n';
    }
}

int main() {
#ifdef ONLINE_JUDGE
    solve();
#else
    std::cout << "Hello World" << '\n';
#endif
}
Back to top page