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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章