列表

详情


NC217953. Alice,BobandPlayGame

描述

牛牛的英文名叫,牛妹的英文名叫故事从下面展开:

黑板上有个整数,初始时
进行轮游戏,第轮游戏流程如下:
选择两个不同的整数,并令
做以下操作之一:
0.令
1.令

为进行了轮游戏后的值。
令序列
想让的字典序尽可能的小,想让的字典序尽可能的大。

很快意识到这是一个不公平的游戏,因为只要足够聪明,一定会有。于是启用了时之魔法,预测了在每轮会选择的整数对。

但是很快又意识到,只要足够聪明,的操作策略会根据操作的策略发生改变,仍然会有。这将可能导致每轮选择的整数对和预测的整数对不一样。而的预测是不可以失效的,因为一旦的预测失效,时空将会发生扭曲,这会造成非常严重的后果。因此,又使用了馄饨赤光魔法使得在进行轮游戏时智商下降。

确切地说,知道在第轮游戏一定会选择整数对

且Bob需要保证如下条件
在第轮游戏结束后,满足

想知道在他保证条件的基础上字典序最大的序列是什么样子,此外,他还想知道他的操作序列。

输入描述

第一行两个整数
接下来行每行两个整数

输出描述

第一行个整数
第二行一个长度为表示轮游戏进行的操作。
有多种合法的操作序列只需要输出任意一种即可。

示例1

输入:

6 5
1 2
3 4
2 3
2 5
1 6

输出:

5 4 4 4 4
00100

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 153ms, 内存消耗: 17140K, 提交时间: 2021-06-06 20:55:55

#include<bits/stdc++.h>
#define R int
#define I inline
#define ll long long
using namespace std;
const int N=2e5+3;
int to[N],p[N],ln[N],res[N];
vector<int>f[N<<1];
void work(int u)
{
	res[u>>1]=u&1;
	for(auto v:f[u])work(v);
}
void add(int x,int y){to[x]=y;to[y]=x;}
void link(int x,int y){f[x].push_back(y);}
int main()
{
	int n,m,c;
	scanf("%d%d",&n,&m);c=n;
	for(R i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		if(!to[u]&&!to[v])
		{
			--c;
			add(u,v);
			ln[u]=i<<1|1;ln[v]=i<<1;
		}
		else
		{
			if(to[u]&&to[v])
			{
				if(to[u]==v)work(ln[u]);
				else
				{
					int x=to[u],y=to[v];
					link(ln[x],ln[v]);
					link(ln[y],ln[u]);
					add(u,v);add(x,y);
				}
			}
			else
			{
				int w=to[u]|to[v];
				work(ln[w]);
				to[w]=0;
				add(u,v);
			}
			ln[u]=i<<1;ln[v]=i<<1|1;
		}
		printf("%d ",c);
	}
	puts("");
	for(R i=1;i<=n;i++)
		if(to[i])work(ln[i]),to[to[i]]=0;
	for(R i=1;i<=m;i++)printf("%d",res[i]);
	return 0;
}

上一题