Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! F. Johnny and Megan’s Necklace(思维+欧拉回路)

F. Johnny and Megan's Necklace

time limit per test

3 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Johnny's younger sister Megan had a birthday recently. Her brother has bought her a box signed as "Your beautiful necklace — do it yourself!". It contains many necklace parts and some magic glue.

The necklace part is a chain connecting two pearls. Color of each pearl can be defined by a non-negative integer. The magic glue allows Megan to merge two pearls (possibly from the same necklace part) into one. The beauty of a connection of pearls in colors uu and vv is defined as follows: let 2k2k be the greatest power of two dividing u⊕vu⊕v — exclusive or of uu and vv. Then the beauty equals kk. If u=vu=v, you may assume that beauty is equal to 2020.

Each pearl can be combined with another at most once. Merging two parts of a necklace connects them. Using the glue multiple times, Megan can finally build the necklace, which is a cycle made from connected necklace parts (so every pearl in the necklace is combined with precisely one other pearl in it). The beauty of such a necklace is the minimum beauty of a single connection in it. The girl wants to use all available necklace parts to build exactly one necklace consisting of all of them with the largest possible beauty. Help her!

Input

The first line contains nn (1≤n≤5⋅105)(1≤n≤5⋅105) — the number of necklace parts in the box. Each of the next nn lines contains two integers aa and bb (0≤a,b<220)(0≤a,b<220), which denote colors of pearls presented in the necklace parts. Pearls in the ii-th line have indices 2i−12i−1 and 2i2i respectively.

Output

The first line should contain a single integer bb denoting the maximum possible beauty of a necklace built from all given parts.

The following line should contain 2n2n distinct integers pipi (1≤pi≤2n)(1≤pi≤2n) — the indices of initial pearls in the order in which they appear on a cycle. Indices of pearls belonging to the same necklace part have to appear at neighboring positions in this permutation (so 14321432 is not a valid output, whereas 21432143 and 43124312 are). If there are many possible answers, you can print any.

Examples

input

Copy

5
13 11
11 1
3 5
17 1
9 27

output

Copy

3
8 7 9 10 5 6 1 2 3 4 

input

Copy

5
13 11
11 1
3 5
17 1
7 29

output

Copy

2
8 7 10 9 5 6 4 3 2 1 

input

Copy

1
1 1

output

Copy

20
2 1 

Note

In the first example the following pairs of pearls are combined: (7,9)(7,9), (10,5)(10,5), (6,1)(6,1), (2,3)(2,3) and (4,8)(4,8). The beauties of connections equal correspondingly: 33, 33, 33, 2020, 2020.

The following drawing shows this construction.

 

 

 

题意:

给你n(<=5e5)根木棒,每个木棒两端有一个值v(<2^20),按端点标号1~2*n。

如果将一个木棒端点值为x的一端连接另一个木棒端点值为y的端点,那么会产生一个边权,权值为lowbit(x^y)对应的2的幂次。如果x==y,那么边权为20。

现在让你找到一个最小边权值最大的连接,使得所有木棒连接成一个环。输出任意一个合法方案(端点值序号)。注意,输出时木棒的两端应在相邻的位置(也就是4312可以而2431不可以)。

思路:

考虑从大到小枚举最大的边权值k,则

端点值x与端点值y的端点连接的条件是x&((1<<k)-1)==y&((1<<k)-1),即二进制后k位完全相同(这样x^y才能整除2的k次方)。

这样我们最后求一个哈密顿回路就可以得到答案。然而复杂度显然不允许,并且我们无法保证木棒的两端在答案中是相邻的。

接下来就是本题的关键:

对于某个k,只有二进制后k位相同的端点才可以连边,我们可以直接将由k位组成的所有二进制当做新点,直接用木棒去连他(注意,已经是化端点为边了,木棒的端点为边,木棒和2^k个值是点)。

这个时候,图是欧拉图即存在符合要求的答案(这里需要仔细思考)。

注意本题的坑点:

1、时限非常严格,访问过的边要直接删掉,否则会T,不删边二分k都没用。

2、注意数组大小,以及输出中木棒相邻的两端在答案中也要相邻。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mst(head,x,n) memset(head+1,x,n*sizeof(head[0]))
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=6e5+30;
//const double pi=acos(-1.0);
//const double eps=1e-9;
//const ll mo=1e9+7;
int n,m,k;
int a[maxn],c[maxn];
int cnt,as;
int flag;
bool ok[maxn<<1];
template <typename T>
inline void read(T &X){
    X=0;int w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    if(w) X=-X;
}
vector<vector<pair<int,int> > >vc;
vector<vector<pair<int,int> > >::iterator it;
vector<int>ans,tmp;
void dfs(int u,int x){
    while(!vc[u].empty()){
        pair<int,int> it=vc[u].back();
        vc[u].pop_back();
        int v=it.first;
        int id=it.second;
        if(!ok[id]){
            ok[id]=true;
            dfs(v,id);
        }
    }
    if(x!=-1) tmp.push_back(x);
}
int jud(int k){
    int t=(1<<k)-1;
    vc.clear();
    vc.resize(t+1+n);
    rep(i,0,2*n) ok[i]=false;

    rep(i,0,n-1){
        vc[i+t+1].push_back(make_pair(a[i]&t,i<<1));
        vc[a[i]&t].push_back(make_pair(i+t+1,i<<1));
        vc[i+t+1].push_back(make_pair(c[i]&t,i<<1|1));
        vc[c[i]&t].push_back(make_pair(i+t+1,i<<1|1));
    }

    rep(i,0,t) if(vc[i].size()&1) return 0;

    tmp.clear();
    rep(i,0,t){
        if(vc[i].size()) {dfs(i,-1);break;}
    }
    if(tmp.size()<2*n) return 0;
    return 1;
}
int main(){
    int T,cas=1;
    //read(T);
    //while(T--)
    {
        read(n);
        rep(i,0,n-1){
            read(a[i]);
            read(c[i]);
        }
        int l=0,r=20;
        if(jud(r)) {
            as=r;
            ans=tmp;
        }
        else while(l<r){
            int mid=(l+r)>>1;
            if(jud(mid)) {
                l=mid+1;
                as=mid;
                ans=tmp;
            }
            else r=mid;
        }
        printf("%d\n",as);
        rep(i,0,2*n-1)
        printf("%d%c",ans[i]+1,i==2*n-1?'\n':' ');
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值