Submission #642707

# Submission time Handle Problem Language Result Execution time Memory
642707 2022-09-20T11:59:50 Z MadokaMagicaFan Traffickers (RMI18_traffickers) C++17
90 / 100
3500 ms 29076 KB
#include "bits/stdc++.h"

/* #define ONPC */
#define sz(v)       ((int)(v.size()))
#define pb          push_back

using ll = long long;

using namespace std;

struct aib{
    vector<int> f;
    int n;
    aib (int _n) {
        f.assign(_n, 0);
        n = _n;
    }

    void add(int x, int v) {
        for (; x < n; x |= (x+1))
            f[x] += v;
    }

    int ask(int x) {
        int res = 0;
        for (; x >= 0; x = (x&(x+1)) - 1)
            res += f[x];
        return res;
    }

    int ask(int l, int r) {
        if (l > r)
            swap(l,r);
        return ask(r) - ask(l-1);
    }
};

int n;
vector<int> p;
vector<int> c;
vector<int> hv;
vector<int> head;
vector<int> d;
vector<int> in;
vector<aib> tr[20];

int icnt = 0;

int
lca(int a, int b)
{
    while (head[a] != head[b]) {
        if (d[head[a]] > d[head[b]])
            a = p[head[a]];
        else
            b = p[head[b]];
    }
    if (d[a] > d[b])
        a = b;
    return a;
}

int
dist(int a, int b)
{
    return d[a] + d[b] - 2 * d[lca(a,b)] + 1;
}

int
dfs(vector<vector<int>> &adj, int x)
{
    int cnt, mcnt = 0;
    for (int u : adj[x]) {
        if (u == p[x]) continue;
        ++c[x];

        p[u] = x;
        d[u] = d[x] + 1;
        cnt = dfs(adj,u);
        if (cnt > mcnt) {
            mcnt = cnt;
            hv[x] = u;
        }
    }

    for (int u : adj[x]) {
        if (u == p[x]) continue;

    }
    return c[x];
}

void
dfs_head(vector<vector<int>> &adj, int x, int h)
{
    head[x] = h;
    in[x] = icnt++;
    if (hv[x])
        dfs_head(adj,hv[x],h);
    for (int u : adj[x]) {
        if (u == p[x]) continue;
        ++c[x];

        if (hv[x] != u)
            dfs_head(adj,u,u);
    }
    return;
}

void
addline(int a, int b, int dif)
{
    int l = lca(a,b);
    int x, c = 0;
    int dist = d[a] + d[b] + 1 - 2 * d[l];
    x = 1;
    while (x * dist < 11)
        ++x;

    while (a != l) {
        if (dist > 1 && dist < 11) {
            for (int j = c; j < x*dist; ++j) {
                if ((j % dist) < c)
                    tr[x*dist-1][j].add(in[a], (j/dist)*dif);
                else
                    tr[x*dist-1][j].add(in[a], (j/dist + 1)*dif);
            }
        } else {
            for (int j = c; j < dist; ++j)
                tr[dist-1][j].add(in[a], dif);
        }
        ++c;
        a = p[a];
    }

    if (dist > 1 && dist < 11) {
        for (int j = c; j < x*dist; ++j) {
            if ((j % dist) < c)
                tr[x*dist-1][j].add(in[l], (j/dist)*dif);
            else
                tr[x*dist-1][j].add(in[l], (j/dist + 1)*dif);
        }
    } else {
        for (int j = c; j < dist; ++j) {
            tr[dist-1][j].add(in[l], dif);
        }
    }

    c = dist - 1;
    while (b != l) {
        if (dist > 1 && dist < 11) {
            for (int j = c; j < x*dist; ++j) {
                if ((j % dist) < c)
                    tr[x*dist-1][j].add(in[b], (j/dist)*dif);
                else
                    tr[x*dist-1][j].add(in[b], (j/dist + 1)*dif);
            }
        } else {
            for (int j = c; j < dist; ++j)
                tr[dist-1][j].add(in[b], dif);
        }
        --c;
        b = p[b];
    }
    return;
}

void
init()
{
    vector<vector<int>> adj(n);
    int a, b;
    for (int i = 0; i < n-1; ++i) {
        cin >> a >> b;
        --a,  --b;
        adj[a].pb(b);
        adj[b].pb(a);
    }

    p.assign(n,0);
    c.assign(n,0);
    d.assign(n,0);
    in.assign(n,0);
    hv.assign(n,0);
    head.assign(n,0);

    dfs(adj,0);
    dfs_head(adj,0,0);

    for (int i = 0; i < 20; ++i) {
        for (int j = 0; j < i+1; ++j) {
            tr[i].pb(aib(n));
        }
    }

    return;
}

ll
answer(int a, int b, int t, int z)
{
    static ll ans;
    static ll difs[20][3];

    ans = 0;

    for (int i = 11; i <= 20; ++i) {
        difs[i-1][0] = (t % i) - 1;
        difs[i-1][1] = (z/i) - (t/i);
        difs[i-1][2] = z % i;
    }

    difs[0][1] = z-t+1;

    /* for (int i = 2; i < 6; ++i) { */
    /*     cout << difs[i-1][0] << ' ' << difs[i-1][1] << ' ' << difs[i-1][2] << endl; */
    /* } */


    while (head[a] != head[b]) {
        if (d[head[a]] > d[head[b]]) {
            ans += difs[0][1] * ((ll)(tr[0][0].ask(in[head[a]], in[a])));
            for (int i = 11; i < 21; ++i) {
                ans += difs[i-1][1] * ((ll)(tr[i-1][i-1].ask(in[head[a]], in[a])));
                ans += ((ll)(tr[i-1][difs[i-1][2]].ask(in[head[a]], in[a])));
                if (difs[i-1][0] > -1)
                ans -= ((ll)(tr[i-1][difs[i-1][0]].ask(in[head[a]], in[a])));
            }
            a = p[head[a]];
        } else {
            ans += difs[0][1] * ((ll)(tr[0][0].ask(in[head[b]], in[b])));
            for (int i = 11; i < 21; ++i) {
                ans += difs[i-1][1] * ((ll)(tr[i-1][i-1].ask(in[head[b]], in[b])));
                ans += ((ll)(tr[i-1][difs[i-1][2]].ask(in[head[b]], in[b])));
                if (difs[i-1][0] > -1)
                ans -= ((ll)(tr[i-1][difs[i-1][0]].ask(in[head[b]], in[b])));
            }
            b = p[head[b]];
        }
    }

    ans += difs[0][1] * ((ll)(tr[0][0].ask(in[a], in[b])));
    for (int i = 11; i < 21; ++i) {
        ans += difs[i-1][1] * ((ll)(tr[i-1][i-1].ask(in[a], in[b])));
        ans += ((ll)(tr[i-1][difs[i-1][2]].ask(in[a], in[b])));
        if (difs[i-1][0] > -1)
        ans -= ((ll)(tr[i-1][difs[i-1][0]].ask(in[a], in[b])));
    }

    /* for (int i = 2; i < 21; ++i) { */
    /*     ans += an[i-1]; */
    /* } */
    /* cout << endl; */

    return ans;
}

int32_t
main(int argc, char *argv[])
{
#ifdef ONPC
    if (argc > 1)
        freopen(argv[1], "r", stdin);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;

    init();
    int k, q, a, b;

    cin >> k;
    while (k--) {
        cin >> a >> b;
        --a, --b;
        /* assert(a!=b); */
        addline(a,b,1);
    }

    cin >> q;

    int c, t, z;

    while (q--) {
        cin >> c >>  a >> b;
        --a, --b;
        if (c < 3) {
            addline(a,b, (c == 1) ? 1 : -1);
        } else {
            cin >> t >> z;
            cout << answer(a, b, t, z) << endl;
        }
    }
    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 3 ms 1236 KB Output is correct
3 Correct 4 ms 1236 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 132 ms 9612 KB Output is correct
2 Correct 231 ms 8532 KB Output is correct
3 Correct 32 ms 9428 KB Output is correct
4 Correct 175 ms 9684 KB Output is correct
5 Correct 239 ms 9556 KB Output is correct
6 Correct 200 ms 9556 KB Output is correct
7 Correct 182 ms 9432 KB Output is correct
8 Correct 33 ms 9684 KB Output is correct
9 Correct 28 ms 9812 KB Output is correct
# Verdict Execution time Memory Grader output
1 Execution timed out 3576 ms 28040 KB Time limit exceeded
2 Correct 2389 ms 28992 KB Output is correct
3 Correct 585 ms 28372 KB Output is correct
4 Execution timed out 3570 ms 27604 KB Time limit exceeded
5 Correct 1971 ms 27348 KB Output is correct
6 Correct 1084 ms 28832 KB Output is correct
7 Correct 359 ms 29076 KB Output is correct
8 Correct 396 ms 28620 KB Output is correct