codeforces1361C Johnny and Megan‘s Necklace

https://codeforces.com/problemset/problem/1361/C

从高到低位枚举,如果一个项链的答案是ans,那么根据题意等价于这些连接之间末位的ans个bits是相同的,把一对珍珠当一条边,连接末位的bits之间的连线,然后跑欧拉回路,记录边的顺序就行了

从标程里学习了递归的欧拉回路写法,方便记录边的序号,还学了新的输出姿势,涨姿势了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fir first
#define sec second
typedef pair<int,int> p;
const int maxl=1<<20;

int n,m,cas,k,cnt,tot,ansb;
int a[maxl][2],du[maxl],ans[maxl];
int s[maxl],cur[maxl];
bool in[maxl],vis[maxl]; 
vector <p> e[maxl];

inline void prework()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i][0],&a[i][1]);
} 

inline void dfs(int u)
{
	vis[u]=true;
	for(p d:e[u])
	if(!vis[d.fir])
		dfs(d.fir);
}

inline bool jug(int mask)
{
	for(int i=0;i<=mask;i++)
		e[i].clear(),vis[i]=false;
	int u,v,len,cnt;
	for(int i=1;i<=n;i++)
	{
		u=a[i][0]&mask;v=a[i][1]&mask;
		e[u].push_back({v,2*i+1});
		e[v].push_back({u,2*i});
	}
	cnt=0;
	for(int i=0;i<=mask;i++)
	{
		len=e[i].size();
		if(len&1)
			return false;
		if(!vis[i] && len>0)
		{
			if(cnt>0) return false;
			cnt++,dfs(i);
		}
	}
	return true;
}

inline void eular(int u,int pre=-1)
{
	while(e[u].size())
	{
		p d=e[u].back();
		e[u].pop_back();
		if(in[d.sec/2])
			continue;
		in[d.sec/2]=true;
		eular(d.fir,d.sec);
	}
	if(pre!=-1)
	{
		ans[++ans[0]]=pre;
		ans[++ans[0]]=pre^1;
	}
}

inline void solv(int mask)
{
	int len,u,i;
	for(int st=0;st<=mask;st++)
	{
		len=e[st].size();
		if(len>0)
		{
			eular(st);
			return;
		}
	}
}

inline void mainwork()
{
	for(int i=20;i>=0;i--)
	if(jug((1<<i)-1))
	{
		solv((1<<i)-1);ansb=i;
		return;
	}
}

inline void print()
{
	printf("%d\n",ansb);
	for(int i=1;i<=2*n;i++)
		printf("%d%c",ans[i]-1," \n"[i==2*n]);
}

int main()
{
	int t=1;
	//scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值