Submission #1295948

#TimeUsernameProblemLanguageResultExecution timeMemory
1295948ducanh0811Traffickers (RMI18_traffickers)C++20
100 / 100
500 ms110032 KiB
#include <bits/stdc++.h>
#define int                 long long
#define FOR(i, a, b)        for (int i = (a), _b = (b); i <= _b; ++i)
using namespace std;

#define MAXN 30005
int n, k, q;
vector<int> g[MAXN];

struct node {
    int sum;
    int lz;
    node(int _sum = 0, int _lz = 0) {
        sum = _sum;
        lz = _lz;
    }
};

node combine(const node &a, const node &b) {
    node res = node();
    res.sum = a.sum + b.sum;
    return res;
}

struct SMT { 
    int n;
    vector<int> bit; 
    SMT(int _n = 0) { 
        n = _n;
        bit.assign(n + 5, 0); 
    }
    
    void upd(int p, int val) { 
        for (; p <= n; p += p & -p) bit[p] += val; 
    }

    int get(int x) { 
        int res = 0; 
        while (x) res += bit[x], x -= x & -x;
        return res; 
    }

    int get(int u, int v) { 
        return get(v) - get(u - 1); 
    }
} tree[22][22]; 

// struct SMT {
//     int n;
//     vector<node> st;
//     SMT(int _n = 0) {
//         n = _n;
//         st.assign((n << 2) + 5, node());
//     }

//     void pushDown(int id, int l, int r, int mid) {
//         if (st[id].lz == 0) return;
//         st[id << 1].sum += st[id].lz * (mid - l + 1);
//         st[id << 1].lz  += st[id].lz;
//         st[id << 1 | 1].sum += st[id].lz * (r - mid);
//         st[id << 1 | 1].lz  += st[id].lz;
//         st[id].lz = 0;
//     }

//     void upd(int id, int l, int r, int u, int v, int val) {
//         if (v < l || r < u) return;
//         if (u <= l && r <= v) {
//             st[id].sum += val * (r - l + 1);
//             st[id].lz += val;
//             return;
//         }
//         int mid = (l + r) >> 1;
//         pushDown(id, l, r, mid);
//         upd(id << 1, l, mid, u, v, val);
//         upd(id << 1 | 1, mid + 1, r, u, v, val);
//         st[id] = combine(st[id << 1], st[id << 1 | 1]);
//     }
//     void upd(int u, int v, int val) {
//         upd(1, 1, n, u, v, val);
//     }

//     node get(int id, int l, int r, int u, int v) {
//         if (v < l || r < u) return node();
//         if (u <= l && r <= v) return st[id];
//         int mid = (l + r) >> 1;
//         pushDown(id, l, r, mid);
//         return combine(get(id << 1, l, mid, u, v), get(id << 1 | 1, mid + 1, r, u, v));
//     }
//     int get(int u, int v) {
//         return get(1, 1, n, u, v).sum;
//     }
// } tree[22][22];

int child[MAXN], par[MAXN], heavy[MAXN], dep[MAXN];
int pos[MAXN], head[MAXN], timer = 0;

void dfs(int u, int p) {
    child[u] = 1;
    int mx_c = 0;
    for (int &v : g[u]) {
        if (v == p) continue;
        dep[v] = dep[u] + 1;
        par[v] = u;
        dfs(v, u);
        child[u] += child[v];
        if (child[v] > mx_c) {
            mx_c = child[v];
            heavy[u] = v;
        }
    }
}

void hld(int u, int h) {
    head[u] = h;
    pos[u] = ++timer;
    if (heavy[u] != 0) hld(heavy[u], h);
    for (int &v : g[u]) {
        if (v == par[u] || v == heavy[u]) continue;
        hld(v, v);
    }
}

int LCA(int u, int v) {
    while (head[u] != head[v]) {
        if (dep[head[u]] < dep[head[v]]) swap(u, v);
        u = par[head[u]];
    }
    if (dep[u] > dep[v]) swap(u, v);
    return u;
}

void updBIT(int sta, int fin, int val, int length, int id) { 
    FOR(i, sta, fin) tree[length][id].upd(i, val); 
}

void upd(int u, int v, int val, int id, int length) {
    while (head[u] != head[v]) {
        if (dep[head[u]] < dep[head[v]]) swap(u, v);
        updBIT(pos[head[u]], pos[u], val, length, id); 
        u = par[head[u]];
    }
    if (pos[u] > pos[v]) swap(u, v);
    updBIT(pos[u], pos[v], val, length, id);
}

int query(int u, int v, int id, int length) {
    int res = 0;
    while (head[u] != head[v]) {
        if (dep[head[u]] < dep[head[v]]) swap(u, v);
        res += tree[length][id].get(pos[head[u]], pos[u]);
        u = par[head[u]];
    }
    if (pos[u] > pos[v]) swap(u, v);
    res += tree[length][id].get(pos[u], pos[v]);
    return res;
}

void modifyPath(int sta, int fin, int delta) {
    int mid = LCA(sta, fin);
    int numNode = dep[sta] + dep[fin] - 2 * dep[mid] + 1;
    vector<int> up, down;
    while (sta != mid) {
        up.push_back(sta);
        sta = par[sta];
    }
    while (fin != mid) {
        down.push_back(fin);
        fin = par[fin];
    }
    reverse(down.begin(), down.end());
    vector<int> nodes;
    nodes.insert(nodes.end(), up.begin(), up.end());
    nodes.push_back(mid);
    nodes.insert(nodes.end(), down.begin(), down.end());
    FOR(i, 0, nodes.size() - 1) {
        upd(nodes[0], nodes[i], delta, i, numNode);
    }
}

int cost(int t, int delta, int numNode, int a, int b) {
    if (t < 0) return 0;
    int res = 0;
//    cout << "\nhihi: " << delta << " " << res << '\n';
    int full = t / numNode;
    res += delta * query(a, b, numNode - 1, numNode) * full;
//    cout << "\nhaha: " << delta << " " << res << '\n';
    t -= full * numNode;
    res += delta * query(a, b, t, numNode);
    return res;
}

void solve() {
    cin >> n;
    FOR(i, 1, n - 1) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    FOR(i, 0, 20) FOR(j, 0, 20) tree[i][j] = SMT(n);
    dfs(1, 0);
    hld(1, 1);
    cin >> k;
    FOR(i, 1, k) {
        int x, y; cin >> x >> y;
        modifyPath(x, y, 1);
    }
    cin >> q;
    FOR(i, 1, q) {
        int type, a, b;
        cin >> type >> a >> b;
        if (type == 1) modifyPath(a, b, 1);
        else if (type == 2) modifyPath(a, b, -1);
        else if (type == 3) {
            int t1, t2; cin >> t1 >> t2;
            int res = 0;
            FOR(numNode, 1, 20) {
//                cout << "test: " << numNode << " " << cost(t2, 1, numNode, a, b) << " " <<  cost(t1 - 1, -1, numNode, a, b) << '\n';
                res += (cost(t2, 1, numNode, a, b) + cost(t1 - 1, -1, numNode, a, b));
            }
            cout << res << '\n';
        }
    }
}

#define task "test"
int32_t main() {
    if (fopen(task".inp","r")) {
        freopen(task".inp","r",stdin);
        freopen(task".out","w",stdout);
    }
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    return 0;
}

Compilation message (stderr)

traffickers.cpp: In function 'int32_t main()':
traffickers.cpp:228:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  228 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
traffickers.cpp:229:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  229 |         freopen(task".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...