Problem Author: | turneja |
Prepared by: | turneja |
Edited by: | turneja |
Solution
The answer is the sum of f(x,y) where f(x,y) is the number of subsets for which the following holds:
the subset contains at least one occurrence of value ,
the subset contains at least one occurrence of value ,
all chosen elements satisfy x \subseteq a \subseteq y ( must be a supermask of and a submask of ).
It is a known result that \sum_{x=0}^{2^{m}-1} \#\{\, s \mid s \subseteq x \,\} = \sum_{x=0}^{2^{m}-1} 2^{\mathrm{popcount}(x)} = 3^{m}, or the sum of the number of submasks of all integers from to 2^m - 1 is equal to 3^m. Therefore a feasible solution can calculate each possible value f(x,y) explicitely and add it to the solution.
Let us fix , or the bitwise OR of the subset and calculate f(x,y) for each which is a submask of the fixed . Let dp[z] = \sum_{a:\; z \subseteq a \subseteq y} \mathrm{freq}[a]. These values can be calculated quickly with a sum over subsets/superset zeta transform algorithm but only iterating over the submasks of instead of all possible integers.
Then finally f(x,y) can be calculated as f(x,y)= \begin{cases} 2^{\mathrm{freq}[x]}-1, & x=y,\\[6pt] \left(2^{\mathrm{freq}[x]}-1\right)\left(2^{\mathrm{freq}[y]}-1\right)\cdot 2^{\,dp[x]-\mathrm{freq}[x]-\mathrm{freq}[y]}, & x\ne y, \end{cases}
The time complexity will be \mathcal{O}(m3^{m}) where is the maximum of most significant bit of the input integers.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
#define endl "\n"
#define ll long long
#define IOS ios_base::sync_with_stdio(false); cin.tie(nullptr);
const int N = 1e5 + 5;
const ll M = 998244353;
int freq[N];
int dp[N];
ll pw[N];
int main() {
IOS;
pw[0] = 1;
for (int i = 1; i < N; i++) {
pw[i] = pw[i - 1] * 2 % M;
}
int n, mx = 0;
cin >> n;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
freq[a]++;
mx = max(mx, a);
}
int b = 0, p = 1;
while (mx >= p) {
b++;
p *= 2;
}
ll ans = 0;
for (int i = 1; i <= mx; i++) {
if (!freq[i]) {
continue;
}
for (int j = i; j > 0; j = (j - 1) & i) {
dp[j] = freq[j];
}
for (int k = 0; k < b; k++) {
int c = (1 << k) & i;
if (!c) {
continue;
}
for (int j = i; j > 0; j = (j - 1) & i) {
int c = (1 << k) & j;
if (!c) {
dp[j] += dp[j ^ (1 << k)];
}
}
}
for (int j = i; j > 0; j = (j - 1) & i) {
if (j == i) {
ans = (ans + pw[freq[j]] - 1 + M) % M;
} else {
ans = (ans + (pw[freq[j]] - 1) * (pw[dp[j] - freq[j] - freq[i]]) % M * (pw[freq[i]] - 1)) % M;
}
}
}
cout << ans;
return 0;
}