CF1361C Solution

题目链接

题解

可以发现 \(k\) 的取值范围只有 \(20\) ,可以枚举答案。若当前答案 \(i\) 成立,则合并在一起的珍珠后 \(i\) 位一定相等。因此对于每对珍珠 \((a,b)\) ,将 \(a\)\(i\) 位的值与 \(b\)\(i\) ​位的值连边。易得若图中存在欧拉回路则答案成立,该欧拉回路即为项链方案。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10,M=105e4;
struct node {int v,nxt,x,y;} e[2*N];
int a[N],b[N],in[M],st[2*N],top; 
int fst[M],cnt; bool vis[2*N],qwq[M];
void add(int x,int y,int xx,int yy)
{
	in[y]++; e[++cnt].v=y;
	e[cnt].x=xx,e[cnt].y=yy;
	e[cnt].nxt=fst[x],fst[x]=cnt;
}
void dfs(int x)
{
	qwq[x]=1;
	for(int i=fst[x];i;i=fst[x])
	{
		fst[x]=e[i].nxt;
		int y=e[i].v;
		if(vis[i]) continue;
		vis[i]=vis[i^1]=1;
		dfs(y); st[++top]=i;
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
	for(int i=20;i>=1;i--)
	{
		memset(fst,0,sizeof(fst)); cnt=1;
		memset(in,0,sizeof(in));
		memset(vis,0,sizeof(vis)); top=0;
		memset(qwq,0,sizeof(qwq));
		int tmp=(1<<i)-1,x,y,flag=0;
		for(int j=1;j<=n;j++)
		{
			x=a[j]&tmp,y=b[j]&tmp;
			add(x,y,j*2-1,j*2),add(y,x,j*2,j*2-1);
		}
		for(int j=1;j<=n;j++)
		{
			x=a[j]&tmp,y=b[j]&tmp;
			if(in[x]&1 || in[y]&1) {flag=1; break;}
		}
		if(flag) continue;
		dfs(a[1]&tmp);
		for(int j=1;j<=n;j++)
		{
			x=a[j]&tmp,y=b[j]&tmp;
			if(!qwq[x] || !qwq[y]) {flag=1; break;}
		}
		if(flag) continue;
		printf("%d\n",i);
		while(top--) printf("%d %d ",e[st[top+1]].x,e[st[top+1]].y);
		return 0;
	}
	printf("0\n");
	for(int i=1;i<=n;i++) printf("%d %d ",i*2-1,i*2);
	return 0;
}
posted @ 2021-08-12 11:14  violet_holmes  阅读(28)  评论(0编辑  收藏  举报