Codeforces 1361C - Johnny and Megan's Necklace(欧拉回路)
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(欧拉回路)的更多相关文章
- CF1361C Johnny and Megan's Necklace
考虑\(2^x | (u \oplus v)\)的最大\(x\)小于等于\(20\) 这种题目,可以考虑搬到图上做. 我们枚举\(x\)那么对\((u\ mod\ 2^x,v\ mod\ 2^x)\) ...
- Codeforces Round #339 (Div. 1) C. Necklace 构造题
C. Necklace 题目连接: http://www.codeforces.com/contest/613/problem/C Description Ivan wants to make a n ...
- UVA 10054 the necklace 欧拉回路
有n个珠子,每颗珠子有左右两边两种颜色,颜色有1~50种,问你能不能把这些珠子按照相接的地方颜色相同串成一个环. 可以认为有50个点,用n条边它们相连,问你能不能找出包含所有边的欧拉回路 首先判断是否 ...
- 【Codeforces 526D】Om Nom and Necklace
Codeforces 526 D 题意:给一个字符串,求每个前缀是否能表示成\(A+B+A+B+\dots+A\)(\(k\)个\(A+B\))的形式. 思路1:求出所有前缀的哈希值,以便求每个子串的 ...
- UVA-10054.The Necklace(欧拉回路)解题报告
2019-02-09-21:55:23 原题链接 题目描述: 给定一串珠子的颜色对,每颗珠子的两端分别有颜色(用1 - 50 之间的数字表示,对每颗珠子的颜色无特殊要求),若两颗珠子的连接处为同种颜色 ...
- 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 ...
- 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 ...
- Codeforces 91C Ski Base 加边求欧拉回路数量
题目链接:点击打开链接 题意: 给出n个点m条无向边的图 開始图里没有边.每次加一条边,然后输出图里欧拉回路的条数. 思路: We will count the number of ski bases ...
- CodeForces 1103C. Johnny Solving
题目简述:给定简单(无自环.无重边)连通无向图$G = (V, E), 1 \leq n = |V| \leq 2.5 \times 10^5, 1 \leq m = |E| \leq 5 \time ...
随机推荐
- springboot 事务执行全流程分析
springboot 事务执行全流程分析 目录 springboot 事务执行全流程分析 1. 事务方法执行前的准备工作 2. 业务代码的调用 3. 事务方法执行后处理 4. 业务代码在事务和非事务中 ...
- 【UE4 设计模式】简单工厂模式 Simple Factory Pattern
概述 描述 又称为静态工厂方法 一般使用静态方法,根据参数的不同创建不同类的实例 套路 创建抽象产品类 : 创建具体产品类,继承抽象产品类: 创建工厂类,通过静态方法根据传入不同参数从而创建不同具体产 ...
- BUAA_2020_软件工程_个人项目作业
作业抬头(1') 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 了解软件工程的技术,掌握工程化开发的能力 这 ...
- 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解
前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...
- 硬件工程师必须掌握的PCB叠层设计内容
总的来说叠层设计主要要遵从两个规矩: 1. 每个走线层都必须有一个邻近的参考层(电源或地层); 2. 邻近的主电源层和地层要保持最小间距,以提供较大的耦合电容; 下面列出从两层板到八层板的叠层来进行示 ...
- 修炼Servlet
修炼Servlet 一.Servlet简单认识 1.Servlet是什么 Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的 ...
- 攻防世界 杂项 4.something_in_image
这是原题 我这里使用编辑器打开,一看乱码也挺多的,于是想了想ctrl+f搜索一下flag关键字吧,结果答案出来了(flag不少,多搜索几次) Flag{yc4pl0fvjs2k1t7T}
- ASP.NET MVC 中使用 jQuery 实现异步搜索功能
常见的几种异步请求方式: Ajax.BeginForm 异步提交文本的形式 Ajax.ActionLinkk 文本链接的形式 Client Validataion 客户端的认证 一.用jQuer ...
- OpenWrt编译报错:Package airfly_receiver is missing dependencies for the following libraries
今天在编译一个OpenWrt测试用例的时候出现报错 Package airfly_receiver is missing dependencies for the following librarie ...
- hdu 3635 Dragon Balls(并查集)
题意: N个城市,每个城市有一个龙珠. 两个操作: 1.T A B:A城市的所有龙珠转移到B城市. 2.Q A:输出第A颗龙珠所在的城市,这个城市里所有的龙珠个数,第A颗龙珠总共到目前为止被转移了多少 ...