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. springboot 事务执行全流程分析

    springboot 事务执行全流程分析 目录 springboot 事务执行全流程分析 1. 事务方法执行前的准备工作 2. 业务代码的调用 3. 事务方法执行后处理 4. 业务代码在事务和非事务中 ...

  2. 【UE4 设计模式】简单工厂模式 Simple Factory Pattern

    概述 描述 又称为静态工厂方法 一般使用静态方法,根据参数的不同创建不同类的实例 套路 创建抽象产品类 : 创建具体产品类,继承抽象产品类: 创建工厂类,通过静态方法根据传入不同参数从而创建不同具体产 ...

  3. BUAA_2020_软件工程_个人项目作业

    作业抬头(1') 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 了解软件工程的技术,掌握工程化开发的能力 这 ...

  4. 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解

    前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...

  5. 硬件工程师必须掌握的PCB叠层设计内容

    总的来说叠层设计主要要遵从两个规矩: 1. 每个走线层都必须有一个邻近的参考层(电源或地层); 2. 邻近的主电源层和地层要保持最小间距,以提供较大的耦合电容; 下面列出从两层板到八层板的叠层来进行示 ...

  6. 修炼Servlet

    修炼Servlet 一.Servlet简单认识 1.Servlet是什么 Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的 ...

  7. 攻防世界 杂项 4.something_in_image

    这是原题 我这里使用编辑器打开,一看乱码也挺多的,于是想了想ctrl+f搜索一下flag关键字吧,结果答案出来了(flag不少,多搜索几次) Flag{yc4pl0fvjs2k1t7T}

  8. ASP.NET MVC 中使用 jQuery 实现异步搜索功能

    常见的几种异步请求方式: Ajax.BeginForm   异步提交文本的形式 Ajax.ActionLinkk 文本链接的形式 Client Validataion  客户端的认证 一.用jQuer ...

  9. OpenWrt编译报错:Package airfly_receiver is missing dependencies for the following libraries

    今天在编译一个OpenWrt测试用例的时候出现报错 Package airfly_receiver is missing dependencies for the following librarie ...

  10. hdu 3635 Dragon Balls(并查集)

    题意: N个城市,每个城市有一个龙珠. 两个操作: 1.T A B:A城市的所有龙珠转移到B城市. 2.Q A:输出第A颗龙珠所在的城市,这个城市里所有的龙珠个数,第A颗龙珠总共到目前为止被转移了多少 ...