题解 AT5800 【[AGC043C] Giant Graph】
以下设
由于
考虑 dp,设
转移方程为
时间复杂度
考虑如下这样一个博弈问题:
有三张
n 个点的有向图,每张图在某个点上都有一个标记。有两个人轮流进行移动,每次移动可以将一个标记从一条出边移动过去。
谁不能移动了谁就输了。
对于这样一个博弈问题,用
然后可以发现,这个博弈问题的
而这个博弈问题中,三张图之间相互独立。
这让我们想到了
注意到,对于一个 DAG 博弈转移图,
const int N = 1e5 + 7;
const modint K = 1000000000000000000ll % P;
int n;
modint ans;
struct Graph {
int n, m, sg[N], k;
modint c[N];
vi e[N];
inline Graph() {}
inline Graph(int n) : n(n) {}
int SG(int x) {
if (~sg[x]) return sg[x];
map<int, bool> p;
for (int y : e[x]) p[SG(y)] = 1;
while (p[++sg[x]]);
return sg[x];
}
inline void main() {
rd(m);
for (int i = 1; i <= n; i++) sg[i] = -1;
for (int i = 1, x, y; i <= m; i++) {
rd(x), rd(y);
if (x > y) swap(x, y);
e[x].pb(y);
}
for (int i = 1; i <= n; i++) if (!~sg[i]) SG(i);
for (int i = 1; i <= n; i++) k = max(k, sg[i]), c[sg[i]] += K ^ i;
}
} G[3];
int main() {
rd(n);
for (int i = 0; i < 3; i++) G[i] = Graph(n), G[i].main();
for (int i = 0; i <= G[0].k; i++)
for (int j = 0; j <= G[1].k; j++)
ans += G[0].c[i] * G[1].c[j] * G[2].c[i^j];
print(ans);
return 0;
}