题解:P7949 [✗✓OI R1] 左方之地

· · 题解

我愿称为超神脑筋急转弯,准备扔给同学。

最近在补 /contest/55488 这一场的题,发现 ACE 全是神秘构造的时候就在想这场 div.2 怎么出成 arc 了,然后你告诉我这题被 AT 变成了 AT_arc138_d,绷不住了。

做一轮异或差分,容易发现每个位置都是 \text{popcount}(x)=k 的数。

考虑转而用这些数字构造差分数列,我们需要让每一个前缀的异或和互不相同。

众所周知,插进线性基的数字,任意取一个子集出来异或和都是不同的。

那么我们把符合条件的数字插进线性基,如果基满秩那么才可以生成所有数字,此时用格雷码枚举子集即可。

时间复杂度 O(2^nn)

#include<bits/stdc++.h>
using namespace std;
const int MB=60;
int p[MB+5];
bool ins(int x){
    for(int i=MB;i>=0;i--)
    if((1ll<<i)&x){
        if(!p[i]){p[i]=x;return 1;}
        else x^=p[i];
    }
    return 0;
}
vector<int>ve;
int lst;
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<(1<<n);i++)
    if(__builtin_popcount(i)==k)
    if(ins(i))ve.push_back(i);
    if(ve.size()==n){
        cout<<"1\n";
        for(int i=0;i<(1<<n);i++){
            int x=i^(i>>1);
            int flc=0;
            for(int j=0;j<n;j++)
            if((x>>j)&1)flc^=ve[j];
            cout<<flc<<' ';
        }
    }else
    cout<<0;
    return 0;
}
// 这是发生在许久以前,军方预知到将有史上最大的〈第六兽〉来袭时的事。

// 预知的内容显示,珂朵莉‧诺塔‧瑟尼欧里斯非得开门才会赢。
// 当珂朵莉被吩咐要为了世界而死的时候,她毫无畏惧及迷惘,静静地接纳了那样的命运。

// 至少,她的背影在缇亚忒看来是那样的。