QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#179407#6888. TeyvatPPP#AC ✓2331ms228912kbC++175.9kb2023-09-14 21:12:192023-09-14 21:12:20

Judging History

你现在查看的是最新测评结果

  • [2023-09-14 21:12:20]
  • 评测
  • 测评结果:AC
  • 用时:2331ms
  • 内存:228912kb
  • [2023-09-14 21:12:19]
  • 提交

answer

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
//#pragma GCC optimize("O3")
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;


int n, m, q;

namespace batyr {

    const int N = 1e6 + 10;

    const int LOG = 12;
    int tin[N], tout[N], up[N][LOG];
    int timer = 0;
    int depth[N];
    ll solo_ans[N];
    int sz[N];

    bool upper(int v, int u) {
        return tin[v] <= tin[u] && tin[u] <= tout[v];
    }

    int lca(int v, int u) {
        if (upper(v, u))
            return v;
        if (upper(u, v))
            return u;
        for (int i = LOG - 1; i >= 0; i--) {
            for (int z = 0; z < 3; z++) {
                if (!upper(up[v][i], u))
                    v = up[v][i];
            }
        }
        return up[v][0];
    }

    int dist(int v, int u) {
        return depth[v] + depth[u] - 2 * depth[lca(v, u)];
    }

    bool in_path(int v, int u, int w) {
        return dist(v, w) + dist(u, w) == dist(v, u);
    }

    int lift(int v, int u) {
        for (int i = LOG - 1; i >= 0; i--) {
            for (int z = 0; z < 3; z++) {
                if (!upper(up[v][i], u))
                    v = up[v][i];
            }
        }
        return v;
    }


    vector<int> G[N];


    void dfs2(int v, int pr) {
        if (v == pr)
            depth[v] = 0;
        else
            depth[v] = depth[pr] + 1;
        tin[v] = ++timer;
        up[v][0] = pr;
        for (int i = 1; i < LOG; i++)
            up[v][i] = up[up[up[up[v][i - 1]][i - 1]][i - 1]][i - 1];
        sz[v] = (v <= n);
        solo_ans[v] = 1ll * n * (n + 1) / 2;
        for (auto to: G[v]) {
            if (to == pr)
                continue;
            dfs2(to, v);
            sz[v] += sz[to];
            solo_ans[v] -= 1ll * sz[to] * (sz[to] + 1) / 2;
        }
        solo_ans[v] -= 1ll * (n - sz[v]) * (n - sz[v] + 1) / 2;
        tout[v] = timer;
    }

}


const int maxN = 1e6 + 100;
vector<int> g[maxN / 2];
int maxColor = 0;
int tin[maxN / 2], up[maxN / 2];
int timer;
bool used[maxN / 2];

void paint(int v, int color, int par) {
    used[v] = true;
    for (int u: g[v]) {
        if (u == par) continue;
        pair<int, int> it = minmax(u, v);
        if (!used[u]) {
            if (up[u] >= tin[v]) {
                int color = ++maxColor;
                batyr::G[n + color].emplace_back(it.first);
                batyr::G[n + color].emplace_back(it.second);
                batyr::G[it.first].emplace_back(n + color);
                batyr::G[it.second].emplace_back(n + color);
//                byClr[color].emplace_back(it);
                paint(u, color, v);
            } else {
                batyr::G[n + color].emplace_back(it.first);
                batyr::G[n + color].emplace_back(it.second);
                batyr::G[it.first].emplace_back(n + color);
                batyr::G[it.second].emplace_back(n + color);
                paint(u, color, v);
            }
        } else if (tin[u] < tin[v]) {
            batyr::G[n + color].emplace_back(it.first);
            batyr::G[n + color].emplace_back(it.second);
            batyr::G[it.first].emplace_back(n + color);
            batyr::G[it.second].emplace_back(n + color);
        }
    }
}

void dfs(int v, int par) {
    timer++;
    up[v] = tin[v] = timer;
    used[v] = true;
    for (int u: g[v]) {
        if (u == par) continue;
        if (used[u]) {
            up[v] = min(up[v], tin[u]);
        } else {
            dfs(u, v);
            up[v] = min(up[v], up[u]);
        }
    }
}

int k;
int a[maxN + maxN / 2];

void solve_byp() {
    for (int i = 1; i <= n; i++) {
        if (!used[i]) dfs(i, -1);
    }
    for (int i = 1; i <= n; i++) used[i] = false;
    for (int i = 1; i <= n; i++) {
        if (!used[i]) {
            paint(i, maxColor, -1);
        }
    }
}

void solve() {
    cin >> n >> m >> q;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
    }
    solve_byp();
    for (int i = 1; i <= n + maxColor; i++) {
        sort(batyr::G[i].begin(), batyr::G[i].end());
        batyr::G[i].erase(unique(batyr::G[i].begin(), batyr::G[i].end()), batyr::G[i].end());
    }
    batyr::dfs2(1, 1);

    while (q--) {
        cin >> k;
        for (int i = 0; i < k; i++)
            cin >> a[i];
        sort(a, a + k);
        k = unique(a, a + k) - a;
        if (k == 1) {
            cout << batyr::solo_ans[a[0]] << "\n";
            continue;
        }
        bool OK = 1;
        int V, U;
        V = U = a[0];
        for (int i = 1; i < k && OK; i++) {
            if (batyr::in_path(V, U, a[i]))
                continue;
            if (batyr::in_path(V, a[i], U))
                U = a[i];
            else if (batyr::in_path(U, a[i], V))
                V = a[i];
            else
                OK = 0;
        }
        if (!OK) {
            cout << 0 << "\n";
            continue;
        }
        int szV, szU;
        if (!batyr::upper(V, U))
            szV = batyr::sz[V];
        else
            szV = n - batyr::sz[batyr::lift(U, V)];

        if (!batyr::upper(U, V))
            szU = batyr::sz[U];
        else
            szU = n - batyr::sz[batyr::lift(V, U)];
        cout << 1ll * szV * szU << "\n";
    }


    timer = 0;
    for (int i = 1; i <= n; i++) {
        used[i] = false;
    }
    for (int i = 1; i <= n; i++) {
        g[i].clear();
    }

    for (int i = 1; i <= n + maxColor; i++) {
        batyr::G[i].clear();
    }

    maxColor = 0;


    batyr::timer = 0;
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
#endif
    int tst;
    cin >> tst;
    while (tst--) {
        solve();
    }
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 2331ms
memory: 228912kb

input:

1000
92 95 16
76 55
19 12
57 7
39 90
38 89
48 60
29 67
35 52
32 83
10 80
64 11
66 63
90 57
17 70
20 42
31 87
91 41
33 72
12 14
9 38
30 82
72 21
9 81
40 9
73 60
71 82
48 69
70 26
72 34
25 62
10 75
83 92
16 18
34 79
15 72
65 13
64 12
37 63
46 16
32 1
23 78
22 18
78 68
49 78
48 13
39 72
39 44
27 25
20 ...

output:

144
91
92
91
615
91
92
92
91
92
91
90
92
91
270
182
18
32
1
18
1
17
17
3
17
1
1
0
18
18
18
3
1
3
18
48
18
6
1
1
34
32
1
18
4
18
18
3
18
18
18
18
34
18
1
34
1
1
18
18
1
32
2
2
18
6
1
3
3
1
18
18
34
18
32
34
34
15
15
15
15
15
15
15
15
15
2
2
15
28
1
15
15
15
15
15
28
15
2
15
2
15
15
28
15
1
15
1
2
0
1...

result:

ok 693539 lines