P9575 「TAOI-2」喵了个喵 后面忘了是几

定义序列 $b_i=\gcd(a_i,x)$。

当 $n$ 为偶数,直接 $x=1$ 即可。所以我们只考虑 $n$ 为奇数。考虑 $x=2$,序列就变成 一堆 $1$ 一堆 $2$。

如果和为偶数,枚举 $2$ 的个数,相应地找到 $1$ 的个数即可(找不到的话怎么办呢?大家先思考一下)。

如果和为奇数,我们可以证明无解:

若取 $x$ 偶数,原来的 $1$ 还是 $1$,原来的 $2$ 会变但是依然为偶数,奇偶性不变,仍无解;若取 $x$ 奇数,原序列全是奇数,而 $n$ 为奇数,奇数个奇数相加仍为奇数,无解。

看起来到这里就差不多了,然而我们会碰到找不到的情况。例如:

3
2 2 4

此时 $b=\{2,2,2\}$,我们想将其分为 $3+3$,但是找不到 $1$ 啊!

所以上面做法的正确性成立当且仅当 $b$ 中存在 $1$。

那怎么办呢。我们不妨在二进制下看一些数。它们有一些共同的 $0$ 后缀(也有可能没有,即长度为 $0$)。我们将后面公共的 $0$ 全部遮住不看,从第一个存在 $1$ 的位考虑。这里再取 $x=2$ 是显然有 $1$ 存在的。注意到后面公共 $0$ 表示的数即为 $\min(\operatorname{lowbit}(a_i))$,于是我们构造 $x=2\min(\operatorname{lowbit}(a_i))$,对 $\dfrac{a_i}{\min(\operatorname{lowbit}(a_i))}$ 做最简单的 $x=2$ 考虑即可。其原理是 $c\gcd(a,b)=\gcd(ac,ab)$。

赛时比较脑弹写了 set 维护位置,根本不用,凭空多一个 log。用其他东西随便做。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int maxn = 1e6 + 10;

int n;
int a[maxn];
bool b[maxn];
set<int> s[2];
int g = 1e10;

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i], g = min(g, a[i] & -a[i]);
    for (int i = 1; i <= n; i++) a[i] /= g;
    if (!(n & 1)) {
        cout << 1 << endl;
        for (int i = 1; i <= n; i++) cout << (i <= (n >> 1));
    } else {
        for (int i = 1; i <= n; i++) s[a[i] & 1].insert(i);
        if (s[1].size() & 1) puts("-1");
        else {
            cout << g * 2 << endl;
            int tot = s[1].size() / 2 + s[0].size();
            for (int i = 0; i <= s[0].size(); i++) {
                if (tot - i * 2 >= 0 && tot - i * 2 <= s[1].size()) {
                    for (int j = 1; j <= i; j++) {
                        b[*s[0].begin()] = 1;
                        s[0].erase(*s[0].begin());
                    }
                    for (int j = 1; j <= tot - i * 2; j++) {
                        b[*s[1].begin()] = 1;
                        s[1].erase(*s[1].begin());
                    }
                    for (int i = 1; i <= n; i++) cout << b[i];
                    return 0;
                }
            }
        }
    }
    return 0;
}
posted @ 2023-08-20 18:25  TernaKagiri  阅读(4)  评论(0编辑  收藏  举报  来源