AtCoder AGC043C Giant Graph

洛谷传送门

AtCoder 传送门

学长讲的一道神仙题。

思路

由于 1018 非常大,所以可以考虑这样一个贪心:每次取目前能取的 x+y+z 最大的点。因此先将所有边定向,从小的编号连向大的。

fx,y,z 为是否选 (x,y,z),那么 fx,y,z=(x,y,z)(x,y,z)[fx,y,z=0],其中 (x,y,z)(x,y,z) 表示图上有一条 (x,y,z)(x,y,z) 的边。意思就是,若 (x,y,z) 的所有出边都没选,则 (x,y,z) 可以选,否则不能选。

暴力算是 O(n3) 的,卡卡常就能过去了。

考虑图上的博弈问题:一个结点上有标记,有两个人轮流移动,每次移动可以将一个标记移动到它的任意一条出边所连向的另一个结点,无法移动的人输。

那么我们发现三个图都是独立的,并且必败态相当于 dp 中的 fx,y,z=1。因此将三个图的 SG 函数算出来再异或得到整个博弈的 SG 函数,答案为 sg0(x)sg1(y)sg2(z)=01018(x+y+z)

注意到对于 m 条边的图的 SG 函数,其最大值是 O(m) 级别的,因此暴力枚举 sg0(x)sg1(y) 再根据异或的性质得到 sg2(z)。预处理出每张图对应 SG 函数的和,再相乘得到答案。总时间复杂度为 O(n+m)

代码

code
/*
p_b_p_b txdy
AThousandMoon txdy
AThousandSuns txdy
hxy txdy
*/
#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
const int maxn = 100100;
const int maxm = 600;
const ll mod = 998244353;
const ll base = 1000000000000000000LL % mod;
int n;
struct graph {
int m, mxk, sg[maxn];
bool vis[maxn];
vector<int> G[maxn];
ll f[maxm];
void dfs(int u) {
if (vis[u]) {
return;
}
vis[u] = 1;
set<int> st;
for (int v : G[u]) {
dfs(v);
st.insert(sg[v]);
}
sg[u] = 0;
while (st.find(sg[u]) != st.end()) {
++sg[u];
}
}
void init() {
scanf("%d", &m);
while (m--) {
int u, v;
scanf("%d%d", &u, &v);
if (u > v) {
swap(u, v);
}
G[u].pb(v);
}
for (int i = 1; i <= n; ++i) {
if (!vis[i]) {
dfs(i);
}
}
ll x = 1;
for (int i = 1; i <= n; ++i) {
mxk = max(mxk, sg[i]);
x = x * base % mod;
f[sg[i]] = (f[sg[i]] + x) % mod;
}
}
} g[3];
void solve() {
scanf("%d", &n);
for (int i = 0; i < 3; ++i) {
g[i].init();
}
ll ans = 0;
for (int i = 0; i <= g[0].mxk; ++i) {
for (int j = 0; j <= g[1].mxk; ++j) {
ans = (ans + g[0].f[i] * g[1].f[j] % mod * g[2].f[i ^ j] % mod) % mod;
}
}
printf("%lld\n", ans);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
posted @   zltzlt  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示