bzoj4730

Alice 和 Bob 又在玩游戏。

有 nn 个节点,mm 条边(0mn10≤m≤n−1),构成若干棵有根树,每棵树的根节点是该连通块内编号最小的点。

Alice 和 Bob 轮流操作(Alice 先手),每回合选择一个没有被删除的节点 xx,将 xx 及其所有祖先全部删除,不能操作的人输。

需要注意的是,树的形态是在一开始就确定好的,删除节点不会影响剩余节点父亲和儿子的关系。

比如:1-3-2 这样一条链,1 号点是根节点,删除 1 号点之后,3 号点还是 2 号点的父节点。

假设 Alice 和 Bob 都足够聪明,问 Alice 有没有必胜策略。

输入格式

第一行一个正整数 TT,表示该测试点有 TT 组数据;接下来 TT 组数据。

对于每组数据:

输入第一行两个整数 nnmm,分别表示点数和边数(节点从 11 开始编号)。

接下来 mm 行,每行两个正整数 aabb,表示节点 aa 和节点 bb 之间有一条边,输入数据中没有重边。

输出格式

输出 TT 行,每行输出 Alice 先手并且 Alice 和 Bob 都足够聪明的情况下谁获胜。

样例

input
4
2 1
1 2
3 2
1 2
1 3
2 0
3 1
1 2

output
Alice
Alice
Bob
Alice

explanation

输入共 4 组数据;

第一组数据输入是一条链,Alice 可以一次性把所有节点都删掉。

第二组数据,Alice 先手第一步删除 1 号点即可胜利。

限制与约定

对于10%10%的数据,m=0m=0;

对于20%20%的数据,1n201≤n≤20;

对于40%40%的数据,1n1021≤n≤102

对于60%60%的数据,1n1031≤n≤103

对于100%100%的数据,1T10,1n105,n2×105,0mn11≤T≤10,1≤n≤105,∑n≤2×105,0≤m≤n−1,输入数据保证不会形成环,且每棵树的大小5×104≤5×104

时间限制2s

对于一个子树的根为root,假定x在以root为根的子树中,那么删除x到根的所有节点之后剩下的游戏状态就是son[z](其中z在x到root的路径上),也就是删掉x的后继状态就是son[z]的sg1值的异或和,那么root的sg值就是他的所以子节点的sg1值的mex。(注意区分sg1和sg)

然后我们发现对于每个根节点他的儿子的sg1值都是不断在变化的,对于一个x,他的sg1值为sg1[son[x]],以及sg1[son[root]](其中x不在son[root]为根的子树中),我们用一个trie维护,每个trie维护的就是某个点到以一个特定点为root的sg1值,假如我们对于一个z已经维护了它到x的sg1值,那么它到fa[x]的sg1值就是相当于它的所有sg1值异或上sg1[son[fa[x]]其中son[fa[x]]!=x。如果用trie维护一个点到某个点的sg1值,那么我们就只要异或上一个数就行了,当然还有支持sg1的合并也就是trie的合并。实现中有一些细节需要注意。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
int f[MAXN], i, n, j, m, k, l, x, y, T;
int first[MAXN], next[MAXN << 1], go[MAXN << 1], t, size[MAXN * 21];
int root[MAXN], s[MAXN * 21][2], nn, d[20], len, cnt[MAXN * 21], ans;
bool vis[MAXN];
inline void add(const int &x, const int &y)
{
	next[++t] = first[x]; first[x] = t; go[t] = y;
}
inline int get()
{
	char c;
	while ((c = getchar()) < 48 || c > 57);
	int res = c - 48;
	while ((c = getchar()) >= 48 && c <= 57)
		res = res * 10 + c - 48;
	return res;
}
inline void rev(int x, int dep, int y)
{
	cnt[x] ^= y;
	if ((y >> (nn - dep - 1)) & 1)
		swap(s[x][0], s[x][1]);
}
inline void putdown(int x, int dep)
{
	if (cnt[x])
	{
		if (s[x][0]) rev(s[x][0], dep + 1, cnt[x]);
		if (s[x][1]) rev(s[x][1], dep + 1, cnt[x]);
		cnt[x] = 0;
	}
}
inline void insert(int x, int sum)
{
	for(int i = 1; i < nn; i ++)
		d[i] = ((sum >> (nn - i - 1)) & 1);
	size[x] ++;
	for(int i = 1; i < nn; i ++)
	{
		if (!s[x][d[i]]) s[x][d[i]] = ++len;
		x = s[x][d[i]];
		size[x] ++;
	}
}
inline int merge(int x, int y, int dep)
{
	if (!x) return y;
	if (!y) return x;
	putdown(y, dep);
	s[x][0] = merge(s[x][0], s[y][0], dep + 1);
	s[x][1] = merge(s[x][1], s[y][1], dep + 1);
	size[x] = size[s[x][0]] + size[s[x][1]];
	if (dep == nn) size[x] = 1;
	return x;
}
inline void dfs(int now, int fa)
{
	vis[now] = 1; f[now] = 0;
	int tot = 0;
	for(int i = first[now]; i; i = next[i])
		if (go[i] != fa) dfs(go[i], now), tot ^= f[go[i]];
	insert(root[now] = ++len, tot);
	for(int i = first[now]; i; i = next[i])
		if (go[i] != fa)
		{
			rev(root[go[i]], 1, tot ^ f[go[i]]);
			root[now] = merge(root[now], root[go[i]], 1);
		}
	int x = root[now];
	for(int i = 1; i < nn; i ++)
	{
		if (!x) break;
		putdown(x, i);
		if (size[s[x][0]] == (1 << (nn - i - 1))) f[now] += (1 << (nn - i - 1)), x = s[x][1];
		else x = s[x][0];
	}
	if (x) f[now] ++;
}
int main()
{
	cin >> T;
	while (T --)
	{
		len = t = 0;
		cin >> n >> m;
		nn = log2(n) + 2;
		memset(vis, 0, sizeof(vis));
		memset(first, 0, sizeof(first));
		memset(s, 0, sizeof(s));
		memset(cnt, 0, sizeof(cnt));
		memset(size, 0, sizeof(size));
		for(i = 1; i <= m; i ++)
		{
			x = get(); y = get();
			add(x, y);
			add(y, x);
		}
		ans = 0;
		for(i = 1; i <= n; i ++)
			if (!vis[i]) dfs(i, 0), ans ^= f[i];
		if (ans) cout << "Alice" << endl;
		else cout << "Bob" << endl;
	}
}


基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现扩展应用。; 适合人群:具备电力系统基础知识Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值