Codeforces 题目传送门 & 洛谷题目传送门

u1s1 感觉这个题作为 D1C 还是蛮合适的……

首先不难发现答案不超过 \(20\),所以可以直接暴力枚举答案并 check 答案是否合法,当然二分也是没问题的,转最优性问题为判定性问题。

考虑怎样判断一个答案 \(k\) 是否合法,由于所有相连的线 \(u,v\) 都有 \(2^k\mid a_u\oplus a_v\),那么 \(a_u\bmod 2^k=a_v\bmod 2^k\) 一定成立。因此我们可以将每个点的权值看作 \(a_i\bmod 2^k\),我们要找出一个串珠子的方法使得每条线的两端权值相等。

我们考虑将此题转化为一个图论问题,对于已经连上线的两点 \(a_i,b_i\),连一条 \(a_i\bmod 2^k\) 与 \(b_i\bmod 2^k\) 的无向边。不难想到欧拉回路。当我们经过 \(a_i\bmod 2^k\) 与 \(b_i\bmod 2^k\) 的边的时候相当于将珠子 \(2i+1,2i+2\) 与刚才串好的线连在了一起。那么如何体现”每条新连的线两端权值相等“呢?不难发现,假设我们先访问了 \(a_i\bmod 2^k\to b_i\bmod 2^k\),紧接着访问了 \(a_j\bmod 2^k\to b_i\bmod 2^k\),那么必须有 \(b_i\bmod 2^k=a_j\bmod 2^k\),这就天然地规定了它们的权值必须相等。因此只需检验建出来的图中是否存在欧拉回路即可。根据”每个点度数都是偶数,并且图须为连通图“即可检验。

找到最大的 \(k\) 后还是按照上述方式建图并跑一遍欧拉回路即可找出方案。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=5e5;
const int MAXMSK=1<<20;
int n,a[MAXN+5],b[MAXN+5];
vector<int> nei[MAXMSK+5];
bool vis[MAXMSK+5];
void dfs(int x){
if(vis[x]) return;vis[x]=1;
for(int i=0;i<nei[x].size();i++) dfs(nei[x][i]);
}
int hd[MAXMSK+5],to[MAXN*2+5],nxt[MAXN*2+5],idu[MAXN*2+5],idv[MAXN*2+5],ec=1;
bool used[MAXN*2+5];
vector<int> ret;
void adde(int u,int v,int x,int y){
to[++ec]=v;idu[ec]=x;idv[ec]=y;nxt[ec]=hd[u];hd[u]=ec;
}
void cir(int x){
for(int &e=hd[x];e;e=nxt[e]) if(!used[e>>1]){
used[e>>1]=1;int u=idu[e],v=idv[e];
cir(to[e]);ret.pb(v);ret.pb(u);
}
}
void end(int x){
int lim=(1<<x)-1;
for(int i=1;i<=n;i++){
adde(a[i]&lim,b[i]&lim,i*2-1,i*2);
adde(b[i]&lim,a[i]&lim,i*2,i*2-1);
} cir(a[1]&lim);
printf("%d\n",x);
for(int u:ret) printf("%d ",u);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
for(int i=20;i;i--){
int lim=(1<<i)-1;
for(int j=0;j<=lim;j++) nei[j].clear(),vis[j]=0;
for(int j=1;j<=n;j++){
nei[a[j]&lim].pb(b[j]&lim);
nei[b[j]&lim].pb(a[j]&lim);
} bool flg=1,hav=0;
for(int j=0;j<=lim;j++) if(nei[j].size()&1){flg=0;break;}
for(int j=0;j<=lim;j++) if(nei[j].size()>=1&&!vis[j]){
if(hav){flg=0;break;}hav=1;dfs(j);
}
if(flg){end(i);return 0;}
} end(0);
return 0;
}

Codeforces 1361C - Johnny and Megan's Necklace(欧拉回路)的更多相关文章

  1. CF1361C Johnny and Megan's Necklace

    考虑\(2^x | (u \oplus v)\)的最大\(x\)小于等于\(20\) 这种题目,可以考虑搬到图上做. 我们枚举\(x\)那么对\((u\ mod\ 2^x,v\ mod\ 2^x)\) ...

  2. Codeforces Round #339 (Div. 1) C. Necklace 构造题

    C. Necklace 题目连接: http://www.codeforces.com/contest/613/problem/C Description Ivan wants to make a n ...

  3. UVA 10054 the necklace 欧拉回路

    有n个珠子,每颗珠子有左右两边两种颜色,颜色有1~50种,问你能不能把这些珠子按照相接的地方颜色相同串成一个环. 可以认为有50个点,用n条边它们相连,问你能不能找出包含所有边的欧拉回路 首先判断是否 ...

  4. 【Codeforces 526D】Om Nom and Necklace

    Codeforces 526 D 题意:给一个字符串,求每个前缀是否能表示成\(A+B+A+B+\dots+A\)(\(k\)个\(A+B\))的形式. 思路1:求出所有前缀的哈希值,以便求每个子串的 ...

  5. UVA-10054.The Necklace(欧拉回路)解题报告

    2019-02-09-21:55:23 原题链接 题目描述: 给定一串珠子的颜色对,每颗珠子的两端分别有颜色(用1 - 50 之间的数字表示,对每颗珠子的颜色无特殊要求),若两颗珠子的连接处为同种颜色 ...

  6. CodeForces - 547D: Mike and Fish (转化为欧拉回路)(优化dfs稠密图)(定向问题)

    As everyone knows, bears love fish. But Mike is a strange bear; He hates fish! The even more strange ...

  7. Codeforces 526.D Om Nom and Necklace

    D. Om Nom and Necklace time limit per test 1 second memory limit per test 256 megabytes input standa ...

  8. Codeforces 91C Ski Base 加边求欧拉回路数量

    题目链接:点击打开链接 题意: 给出n个点m条无向边的图 開始图里没有边.每次加一条边,然后输出图里欧拉回路的条数. 思路: We will count the number of ski bases ...

  9. CodeForces 1103C. Johnny Solving

    题目简述:给定简单(无自环.无重边)连通无向图$G = (V, E), 1 \leq n = |V| \leq 2.5 \times 10^5, 1 \leq m = |E| \leq 5 \time ...

随机推荐

  1. javascriptRemke之类的继承

    前言:es6之前在js中要实现继承,就必须要我们程序员在原型链上手动继承多对象的操作,但是结果往往存在漏洞,为解决这些问题,社区中出现了盗用构造函数.组合继承.原型式继承.寄生式继承等一系列继承方式, ...

  2. [Git系列] Git 基本概念

    版本控制系统 版本控制系统是一种帮助软件开发者实现团队合作和历史版本维护的软件,一个版本控制系统应具备以下列出的这几个基本功能: 允许开发者并发工作: 不允许一个开发者覆写另一个开发者的修改: 保存所 ...

  3. SpringCloud 2020.0.4 系列之服务降级

    1. 概述 老话说的好:做人要正直,做事要正派,胸怀坦荡.光明磊落,才会赢得他人的信赖与尊敬. 言归正传,之前聊了服务间通信的组件 Feign,今天我们来聊聊服务降级. 服务降级简单的理解就是给一个备 ...

  4. spring cloud feign的各种配置的使用

    在上一节我们完成了feign的基本使用,学会了feign如何去调用其他微服务,这次我们来完成feign的一些自定义配置. 实现功能:     1.全局修改feign的配置和单独修改feign客户端的配 ...

  5. STM32入门-STM32时钟系统,时钟初始化配置函数

    在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...

  6. AVL树的插入和删除

    一.AVL 树 在计算机科学中,AVL树是最早被发明的自平衡二叉查找树.在AVL树中,任一节点对应的两棵子树的最大高度差为 1,因此它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度 ...

  7. Codeforces Global Round 16题解

    E. Buds Re-hanging 对于这个题该开始还是没想法的,但这显然是个思维题,还是要多多动手推样例,实践一下. 简化题意:给定一个有根树,规定某个点为树干,当且仅当这个点不是根,且这个点至少 ...

  8. js 组合继承详解

    目录 前言 原型链继承 构造函数继承 组合继承 前言 首先学习继承之前,要对原型链有一定程度的了解. 不了解可以去先阅读我另一篇文章,里面对原型链有一个较为详细的说明:js 原型链详解. 如果已经了解 ...

  9. 有关unsigned和有符号类型的区别

    相信大家对于unsigned这个玩意并不陌生,但是有的时候却会被它搞懵,比如下面: #include<iostream> using std::cout; using std::cin; ...

  10. Git使用教程之初级入门命令行(二)

    一.Git 操作流程图 1.git --help 查看帮助 Administrator@PC-xiaobing MINGW64 /d/Git (master) $ git --help usage: ...