Submission #252359

#TimeUsernameProblemLanguageResultExecution timeMemory
252359IgorISynchronization (JOI13_synchronization)C++17
60 / 100
8061 ms19444 KiB
const int LG = 21;
const int N = 200005;
const long long MOD = 1e9 + 7;
const long long INF = 1e9;
const long long INFLL = 1e18;

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<ll> vll;

#define forn(i, n) for (int (i) = 0; (i) != (n); (i)++)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcount(x) __builtin_popcount(x)
#define popcountll(x) __builtin_popcountll(x)
#define fi first
#define se second
#define re return
#define pb push_back
#define uniq(x) sort(all(x)); (x).resize(unique(all(x)) - (x).begin())

#ifdef LOCAL
#define dbg(x) cerr << __LINE__ << " " << #x << " " << x << endl
#define ln cerr << __LINE__ << endl
#else
#define dbg(x) void(0)
#define ln void(0)
#endif // LOCAL

int n, m, q;

int Get(int pos, vector<int> &tree, int L = 0, int R = n, int V = 0)
{
    if (tree[V] != -1)
    {
        return tree[V];
    }
    int M = (L + R) / 2;
    if (pos < M) return Get(pos, tree, L, M, 2 * V + 1);
    else return Get(pos, tree, M, R, 2 * V + 2);
}

void Set(int l, int r, int x, vector<int> &tree, int L = 0, int R = n, int V = 0)
{
    if (r <= L || R <= l)
    {
        return;
    }
    if (l <= L && R <= r)
    {
        tree[V] = x;
        return;
    }
    int M = (L + R) / 2;
    if (tree[V] != -1) tree[2 * V + 1] = tree[V];
    if (tree[V] != -1) tree[2 * V + 2] = tree[V];
    tree[V] = -1;
    Set(l, r, x, tree, L, M, 2 * V + 1);
    Set(l, r, x, tree, M, R, 2 * V + 2);
}

int Get2(int pos, vector<int> &tree, int L = 0, int R = n - 1, int V = 0)
{
    if (L + 1 == R)
    {
        return tree[V];
    }
    int M = (L + R) / 2;
    if (pos < M) return Get2(pos, tree, L, M, 2 * V + 1);
    else return Get2(pos, tree, M, R, 2 * V + 2);
}

void Set2(int pos, int x, vector<int> &tree, int L = 0, int R = n - 1, int V = 0)
{
    if (L + 1 == R)
    {
        tree[V] = x;
        return;
    }
    int M = (L + R) / 2;
    if (pos < M) Set2(pos, x, tree, L, M, 2 * V + 1);
    else Set2(pos, x, tree, M, R, 2 * V + 2);
    tree[V] = tree[2 * V + 1] + tree[2 * V + 2];
}

int FirstZero(int l, int r, vector<int> &tree, int L = 0, int R = n - 1, int V = 0)
{
    if (r <= L || R <= l)
    {
        return r;
    }
    if (l <= L && R <= r)
    {
        if (tree[V] == R - L) return r;
        if (L + 1 == R) return L;
        int M = (L + R) / 2;
        if (tree[2 * V + 1] == M - L) return FirstZero(l, r, tree, M, R, 2 * V + 2);
        else return FirstZero(l, r, tree, L, M, 2 * V + 1);
    }
    if (tree[V] == R - L) return r;
    int M = (L + R) / 2;
    int a = FirstZero(l, r, tree, L, M, 2 * V + 1);
    if (a != r) return a;
    return FirstZero(l, r, tree, M, R, 2 * V + 2);
}

int LastZero(int l, int r, vector<int> &tree, int L = 0, int R = n - 1, int V = 0)
{
    if (r <= L || R <= l)
    {
        return l - 1;
    }
    if (l <= L && R <= r)
    {
        if (tree[V] == R - L) return l - 1;
        if (L + 1 == R) return L;
        int M = (L + R) / 2;
        if (tree[2 * V + 2] == R - M) return LastZero(l, r, tree, L, M, 2 * V + 1);
        else return LastZero(l, r, tree, M, R, 2 * V + 2);
    }
    if (tree[V] == R - L) return l - 1;
    int M = (L + R) / 2;
    int a = LastZero(l, r, tree, M, R, 2 * V + 2);
    if (a != l - 1) return a;
    return LastZero(l, r, tree, L, M, 2 * V + 1);;
}

void solve_line()
{
    vector<int> le(4 * n, -1), ri(4 * n, -1);
    for (int i = 0; i < n; i++)
    {
        Set(i, i + 1, i, le);
        Set(i, i + 1, i, ri);
    }
    vector<int> act(4 * n, 0);
    for (int i = 0; i < m; i++)
    {
        int z;
        cin >> z;
        z--;
        if (Get2(z, act))
        {
            Set2(z, 0, act);
            continue;
        }
        Set2(z, 1, act);
        int r = FirstZero(z, n - 1, act);
        int l = LastZero(0, z, act);
        l++;
        Set(l, r + 1, Get(z + 1, ri), ri);
        Set(l, r + 1, Get(z, le), le);
    }
    vector<int> ans(n);
    for (int i = 0; i < n; i++)
    {
        ans[i] = Get(i, ri) - Get(i, le) + 1;
    }
    for (int i = 0; i < q; i++)
    {
        int v;
        cin >> v;
        v--;
        cout << ans[v] << "\n";
    }
}

int dfs(int v, int p, int t, vvi &graph, vi &x, vi &y, vector<vector<pii> > &act)
{
    int res = 1;
    for (auto i : graph[v])
    {
        int u = x[i] + y[i] - v;
        if (u != p)
        {
            int L = -1, R = act[i].size();
            while (L + 1 < R)
            {
                int M = (L + R) / 2;
                if (act[i][M].first <= t)
                    L = M;
                else
                    R = M;
            }
            if (L == -1) continue;
            int T = min(act[i][L].second, t);
            res += dfs(u, v, T, graph, x, y, act);
        }
    }
    return res;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> q;
    vector<int> x(n - 1), y(n - 1);
    vector<vector<int> > graph(n);
    int line = 1;
    for (int i = 0; i < n - 1; i++)
    {
        cin >> x[i] >> y[i];
        x[i]--, y[i]--;
        if (x[i] != i || y[i] != i + 1) line = 0;
        graph[x[i]].push_back(i);
        graph[y[i]].push_back(i);
    }
    if (line)
    {
        solve_line();
        return 0;
    }
    vector<int> fr(n - 1, -1);
    vector<vector<pii> > act(n - 1);
    for (int i = 0; i < m; i++)
    {
        int z;
        cin >> z;
        z--;
        if (fr[z] == -1)
        {
            fr[z] = i;
        }
        else
        {
            act[z].push_back({fr[z], i});
            fr[z] = -1;
        }
    }
    for (int i = 0; i < n - 1; i++)
    {
        if (fr[i] != -1)
        {
            act[i].push_back({fr[i], m});
        }
    }
    for (int i = 0; i < q; i++)
    {
        int v;
        cin >> v;
        v--;
        cout << dfs(v, v, m, graph, x, y, act) << "\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...