QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#179407 | #6888. Teyvat | PPP# | AC ✓ | 2331ms | 228912kb | C++17 | 5.9kb | 2023-09-14 21:12:19 | 2023-09-14 21:12:20 |
Judging History
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