QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#179148#6888. TeyvatPPP#ML 0ms0kbC++175.4kb2023-09-14 18:50:502023-09-14 18:50:50

Judging History

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

  • [2023-09-14 18:50:50]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2023-09-14 18:50:50]
  • 提交

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;

const int N = 2000500, LOG = 20;

int n, m, q, k, a[N];
vector<int> g[N], G[N], gg[N];
int depth[N];

int fsz[N];
int sz[N];

int tin[N], tout[N], timer, tup[N];
bool was[N];

int up[N][LOG];

int p[N];

int qid[N];
bool in_bridge[N];

int PR[N];

int pp(int v) {
    return p[v] == v ? v : p[v] = pp(p[v]);
}

void dfs1(int v, int pr) {
    PR[v] = pr;
    tin[v] = tup[v] = ++timer;
    was[v] = 1;
    for (auto to: g[v]) {
        if (to == pr)
            continue;
        if (was[to]) {
            tup[v] = min(tup[v], tin[to]);
        } else {
            dfs1(to, v);
            tup[v] = min(tup[v], tup[to]);
            if (tup[to] <= tin[v]) {
                p[pp(v)] = pp(to);
            }
        }
    }
}

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--)
        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--)
        if (!upper(up[v][i], u))
            v = up[v][i];
    return v;
}

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[v][i - 1]][i - 1];
    was[v] = 1;
    for (auto to: G[v]) {
        if (to == pr || was[to])
            continue;
        dfs2(to, v);
        sz[v] += sz[to];
    }
    tout[v] = timer;
}

bool check(int u) {
    return qid[u] < k && a[qid[u]] == u;
}

void solve() {
    cin >> n >> m >> q;
    for (int i = 0; i < n; i++) {
        g[i].clear();
        G[i].clear();
        gg[i].clear();
    }
    for (int i = 0; i < m; i++) {
        int v, u;
        cin >> v >> u;
        v--, u--;
        g[v].push_back(u);
        g[u].push_back(v);
    }
    for (int i = 0; i < n; i++) {
        p[i] = i;
        was[i] = 0;
        sz[i] = 0;
    }
    dfs1(0, -1);
    for (int i = 0; i < n; i++) {
        sz[pp(i)]++;
        for (auto j: g[i]) {
            G[pp(i)].push_back(pp(j));
            if (pp(i) != pp(j))
                gg[i].push_back(j);
        }
    }
    for (int i = 0; i < n; i++) {
        was[i] = 0;
    }
    dfs2(pp(0), pp(0));
    for (int i = 0; i < n; i++) {
        for (auto j: gg[i]) {
            if (up[pp(j)][0] == pp(i))
                fsz[i] += sz[pp(j)];
            else
                fsz[i] += n - sz[pp(i)];
        }
    }
    while (q--) {
        cin >> k;
        for (int i = 0; i < k; i++) {
            cin >> a[i];
            a[i]--;
        }
        sort(a, a + k);
        k = unique(a, a + k) - a;
        if (k == 1) {
            ll ans = n;
            int sz = fsz[a[0]];
            ans += 1ll * (n - 1 - sz) * (sz);
            cout << ans << "\n";
            continue;
        }
        for (int i = 0; i < k; i++) {
            qid[a[i]] = i;
            in_bridge[i] = 0;
        }
        bool OK = 1;
        int V, U;
        V = U = pp(a[0]);
        for (int i = 1; i < k && OK; i++) {
            if (in_path(V, U, pp(a[i])))
                continue;
            if (in_path(V, pp(a[i]), U))
                U = pp(a[i]);
            else if (in_path(U, pp(a[i]), V))
                V = pp(a[i]);
            else
                OK = 0;
        }
        if (!OK) {
            cout << 0 << "\n";
            continue;
        }
        for (int i = 0; i < k; i++) {
            int v = a[i];
            int u = PR[a[i]];
            if (pp(v) == pp(u) || !in_path(V, U, pp(u)))
                continue;
            in_bridge[qid[v]] = 1;
            if (check(u))
                in_bridge[qid[u]] = 1;
        }
        bool fV = 0, fU = 0;
        int aV = -1, aU = -1;
        for (int i = 0; i < k && OK; i++) {
            if (in_bridge[i])
                continue;
            if (pp(a[i]) == V && !fV)
                fV = 1, aV = a[i];
            else if (pp(a[i]) == U && !fU)
                fU = 1, aU = a[i];
            else
                OK = 0;
        }
        if (!OK) {
            cout << 0 << "\n";
            continue;
        }
        int szV = 1, szU = 1;
        if (fV) {
            szV += fsz[aV];
        } else {
            if (!upper(V, U))
                szV = sz[V];
            else
                szV = n - sz[lift(U, V)];
        }
        if (fU) {
            szU += fsz[aU];
        } else {
            if (!upper(U, V))
                szU = sz[U];
            else
                szU = n - sz[lift(V, U)];
        }
//        cerr << szV << " " << szU << endl;
//        cerr << aV << " " << aU << endl;
        cout << 1ll * szV * szU << "\n";
    }
}

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

詳細信息

Test #1:

score: 0
Memory Limit Exceeded

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
602
91
92
92
91
92
91
90
92
91
270
92
-6716
32
4416
-9810
8464
17
17
8648
17
4416
4416
0
-6716
-9810
-9810
8648
4416
8648
-6716
-7050
-9810
8742
8464
8464
-9810
32
8464
-6716
186
-6716
-9810
8648
-9810
-1392
-6716
-6716
-9810
-9810
8464
-9810
8464
4416
-6716
-6716
8464
32
184
184
-1392
...

result: