题解:AT_arc205_e [ARC205E] Subset Product Problem

· · 题解

AT_arc205_e [ARC205E] Subset Product Problem

如果没有 i\le k 的限制就是 FWT 板子。发现如果你对于当前 a_k 暴力枚举子集或对于 a_i 暴力枚举超集都是不行的,但是发现可以平衡一下。具体的,设 sum_{x,y} 表示前 10 位是 x,后 10 位是 y 的子集。每次更新或询问都是 O(2^{10}) 的。

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
using namespace std;

const int maxn = 5e6 + 5;
const int maxm = 2049;
const int mod = 998244353;
int n, a[maxn], B = (1 << 10) - 1, sum[maxm][maxm];

void insert(int x){
    int y = x & B, w = x;
    x >>= 10;
    for(int s = B ^ y; ; s = (s - 1) & (B ^ y)){
        sum[x][B ^ s] = 1ll * sum[x][B ^ s] * w % mod;
        if(!s) break;
    }
}

int query(int x){
    int y = x & B, ans = 1;
    x >>= 10;
    for(int s = x; ; s = (s - 1) & x){
        ans = 1ll * ans * sum[s][y] % mod;
        if(!s) break;
    }
    return ans;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    for(int i = 0; i < 1 << 10; i++) for(int j = 0; j < 1 << 10; j++) sum[j][i] = 1;
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        insert(a[i]);
        cout << query(a[i]) << '\n';
    }

    return 0;
}