开始 2025-02-10 11:58:28

【2025noip】20250210更正

结束 2025-02-28 00:00:00
Contest is over.
当前 2025-07-07 09:27:27

T3 代码
// Author: Aquizahv
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5, W = 50, w = 40;
const ll all = (1ll << 40) - 1;
int n;
ll a[N], v[W], unit[W], filt[W], f[(1 << 20) + 5], ans;
// unit: 题解里的“f数组”
// filt: 如果选了第 i 位的 unit[i] 进行或运算,还可以选的 unit[j] 的集合
// f: 对于一个集合(集合内 unit[i] 0 <= i <= 19),有多少子集是合法的(即不相互矛盾)
bool vis[W]; // 出现的数位

inline ll read()
{
    ll x = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    { ch = getchar(); }
    while (ch >= '0' && ch <= '9')
    { x = (x << 1ll) + (x << 3ll) + (ch ^ 48); ch = getchar(); }
    return x;
}

void print(ll mask)
{
    for (int k = 0; k < 40; k++)
        putchar(((mask >> k) & 1) + '0');
    putchar('\n');
}

void dfs(int i, ll mask)
{
    if (i >= 40)
    {
        ans += f[mask & ((1 << 20) - 1)];
        return;
    }
    dfs(i + 1, mask);
    if (vis[i] && (mask & (1ll << i)))
        dfs(i + 1, mask & filt[i]);
}

int main()
{
    n = read();
    int gca = all;
    for (int i = 1; i <= n; i++)
    {
        a[i] = read();
        gca &= a[i];
    }
    for (int k = 0; k < 40; k++)
        unit[k] = filt[k] = all;
    for (int i = 1; i <= n; i++)
    {
        a[i] ^= gca;
        for (int k = 0; k < 40; k++)
            if ((a[i] >> k) & 1)
            {
                vis[k] = true;
                unit[k] &= a[i];
            }
    }
    // if i include j, then cannot choose both
    // && the ks which doesnt appear (extra check) (included)
    for (int i = 0; i < 40; i++)
        for (int j = 0; j < 40; j++)
            if ((i != j || !vis[i]) && ((unit[i] & unit[j]) == unit[i] || (unit[i] & unit[j]) == unit[j]))
            {
                filt[i] &= all ^ (1ll << j);
                filt[j] &= all ^ (1ll << i);
            }
    // FMT 20~39
    for (int mask = 0; mask < (1 << 20); mask++)
    {
        bool flag = true;
        for (int k = 0; k < 20; k++)
            if ((mask & (1 << k)) && (mask & filt[k]) != mask)
            {
                flag = false;
                break;
            }
        if (!flag)
            continue;
        f[mask]++;
    }
    for (int k = 0; k < 20; k++)
        for (int mask = 0; mask < (1 << 20); mask++)
            if (mask & (1 << k))
                f[mask] += f[mask ^ (1 << k)];
    // DFS 0~19
    dfs(20, all);
    cout << ans << endl;
    return 0;
}

Aquizahv  •  4个月前

有问题可以问哦


Aquizahv  •  4个月前

比赛已结束。