题意

给出 \(n\) 个数 \(\{a_1, \cdots, a_n\}\),从中选出两个互不相交的集合(不能都为空),使得第一个集合与第二个集合内的数的异或和相等,求总方案数 \(\bmod 998244353\) 。

\(n, a_i \le 10^6\)

题解

简单转化一下,其实就是对于每个选取集合中元素异或积为 \(0\) 的集合,都会有 \(2^{|S|}\) 的贡献。

用集合幂级数形式写出来其实就等价于:

\[\prod_{i = 1}^{n} (1 + 2x^{a_i})
\]

把每个 \(\text{FWT}\) 再乘显然不现实。观察一下 \(1 + 2x^{a_i}\) \(\text{FWT}\) 后的点值只可能是 \(\{-1, 3\}\) 。

这样我们把所有原来的幂级数相加,然后一起 \(\text{FWT}\) 。(因为 \(\text{FWT}\) 是可以满足点值上的加减乘除,与集合对称差卷积上的加减乘除是一样的)

然后每一位算一下,假设有 \(x\) 个 \(-1\) ,\(n - x\) 个 \(3\) 。考虑解一下这个方程,也就是 \(-x + 3 * (n - x) = f_i\) ,也就是 \(\displaystyle x = \frac {3n - f_i}{4}\) 。

那么所有一开始的幂级数 \(\text{FWT}\) 乘到一起其实也就是 \((-1)^x3^{n - x}\) 。

那么最后 \(\text{IFWT}\) 就行了。

最后要减去空集的贡献,注意要 + Mod - 1 (好多人被坑了 \(97pts\) )。

复杂度是 \(\mathcal O(n \log n)\) 的。

代码

#include <bits/stdc++.h>

#define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl using namespace std; typedef long long ll; template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; } inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
} void File() {
#ifdef zjp_shadow
freopen ("310.in", "r", stdin);
freopen ("310.out", "w", stdout);
#endif
} const int len = 1 << 20, N = len << 1, Mod = 998244353, inv2 = (Mod + 1) / 2; inline int fpm(int x, int power) {
int res = 1;
for (; power; power >>= 1, x = 1ll * x * x % Mod)
if (power & 1) res = 1ll * res * x % Mod;
return res;
} void FWT(ll *P, int opt) {
for (int i = 2, p = 1; i <= len; p = i, i <<= 1)
for (int j = 0; j < len; j += i) Rep (k, p) {
ll u = P[j + k], v = P[j + k + p];
P[j + k] = u + v; P[j + k + p] = u - v;
}
if (!~opt) {
int inv = fpm(len, Mod - 2);
Rep (i, len) P[i] = 1ll * (Mod + P[i] % Mod) * inv % Mod;
}
} ll A[N], pow3[N]; int main () { File(); int n = read(); pow3[0] = 1;
For (i, 1, n)
++ A[0], A[read()] += 2, pow3[i] = pow3[i - 1] * 3ll % Mod; FWT(A, 1);
Rep (i, len) {
int x = (3 * n - A[i]) / 4;
A[i] = (Mod + (x & 1 ? -1 : 1) * pow3[n - x]) % Mod;
}
FWT(A, -1); printf ("%lld\n", (A[0] + Mod - 1) % Mod); return 0; }

UOJ#310.【UNR #2】黎明前的巧克力(FWT)的更多相关文章

  1. 【uoj#310】[UNR #2]黎明前的巧克力 FWT

    题目描述 给出 $n$ 个数,从中选出两个互不相交的集合,使得第一个集合与第二个集合内的数的异或和相等.求总方案数. 输入 第一行一个正整数 $n$ ,表示巧克力的个数.第二行 $n$ 个整数 $a_ ...

  2. uoj310【UNR #2】黎明前的巧克力(FWT)

    uoj310[UNR #2]黎明前的巧克力(FWT) uoj 题解时间 对非零项极少的FWT的优化. 首先有个十分好想的DP: $ f[i][j] $ 表示考虑了前 $ i $ 个且异或和为 $ j ...

  3. UOJ #310 黎明前的巧克力 FWT dp

    LINK:黎明前的巧克力 我发现 很多难的FWT的题 都和方程有关. 上次那个西行寺无余涅槃 也是各种解方程...(不过这个题至今还未理解. 考虑dp 容易想到f[i][j][k]表示 第一个人得到巧 ...

  4. UOJ#310 【UNR #2】黎明前的巧克力 FWT 多项式

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ310.html 题目传送门 - UOJ#310 题意 给定 $n$ 个数 ,请你选出两个不相交的集合(两个 ...

  5. UOJ#310. 【UNR #2】黎明前的巧克力(FWT)

    题意 题目链接 Sol 挂一个讲的看起来比较好的链接 然鹅我最后一步还是没看懂qwq.. 坐等SovietPower大佬发博客 #include<bits/stdc++.h> using ...

  6. [UOJ UNR#2 黎明前的巧克力]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 很奇妙的一道题 首先不难发现一个暴力做法,就是f[i]表示异或和为i的答案数,每次FWT上一个F数组,其中F[0]=1,F[ai]=2 ...

  7. UOJ #310 黎明前的巧克力 (FWT)

    题目传送门 题目大意:给你一个序列,定义一个子序列的权值表示子序列中元素的异或和,现在让你选出两个互不相交的子序列,求选出的这两个子序列权值相等的方案数,$n,a_{i}\leq 10^{6}$ 这是 ...

  8. UOJ310. 【UNR #2】黎明前的巧克力 [FWT]

    UOJ 思路 显然可以转化一下,变成统计异或起来等于0的集合个数,这样一个集合的贡献是\(2^{|S|}\). 考虑朴素的\(dp_{i,j}\)表示前\(i\)个数凑出了\(j\)的方案数,发现这其 ...

  9. [UOJ310][UNR #2]黎明前的巧克力

    uoj description 给你\(n\)个数,求从中选出两个交集为空的非空集合异或和相等的方案数模\(998244353\). sol 其实也就是选出一个集合满足异或和为\(0\),然后把它分成 ...

  10. [FWT] UOJ #310. 【UNR #2】黎明前的巧克力

    [uoj#310][UNR #2]黎明前的巧克力 FWT - GXZlegend - 博客园 f[i][xor],考虑优化暴力,暴力就是FWT xor一个多项式 整体处理 (以下FWT代表第一步) F ...

随机推荐

  1. 跨进程SharedPreferences异常。

    诡异的SharedPreferences异常,在ACC之后,SharedPreferences获取不到值了,但是另一个应用可以获取到值.同样的方法,一个正常一个异常. Context c = null ...

  2. Android开发,关于如何在应用间共享SharedPreference

    开发一个应用,需要用到两个应用A和B之间共享数据的问题,这个数据是个单一的数据,所以就想用SharedPrefernce来进行保存. 使用网上的各种应用间的共享代码,B是读取A的数据,所以代码为: C ...

  3. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  4. 一文把samba相关的都说清楚

    1.前言 samba源码都一样,配置也也一样,各个不同linux版本,唯一不同的是对服务的启动方式不同.下面以ubuntu14.4为例,说明. 2. 安装samba samba的安装,可以源码安装,大 ...

  5. AXI-Lite总线及其自定义IP核使用分析总结

    ZYNQ的优势在于通过高效的接口总线组成了ARM+FPGA的架构.我认为两者是互为底层的,当进行算法验证时,ARM端现有的硬件控制器和库函数可以很方便地连接外设,而不像FPGA设计那样完全写出接口时序 ...

  6. MySQL的Limit详解

    问题:数据库查询语句,如何只返回一部分数据? Top子句 TOP 子句用于规定要返回的记录的数目.对于拥有数千条记录的大型表来说,TOP 子句是非常有用的. 在SQL Server数据库中语法为: S ...

  7. JavaScript数据类型之null和undeined

    null null是JavaScrpt的关键字,表示一个特殊值,常用于描述"空值".对null执行typeof运算将返回字符串"object". undefin ...

  8. Java11新特性!

    Java11又出新版本了,我还在Java8上停着.不过这也挡不住我对他的热爱,忍不住查看了一下他的新性能,由于自己知识有限,只总结了以下八个特性: 1.本地变量类型推断 什么是局部变量类型推断? va ...

  9. iOS开发基础-图片切换(1)

    一.程序功能分析 1)点击左右箭头切换图片.序号.描述: 2)如果是首张图片,左边箭头失效: 3)如果是最后一张图片,右边箭头失效. 二.程序实现 定义确定图片位置.大小的常量: //ViewCont ...

  10. Elasticsearch通关教程(一): 基础入门

    简介 Elasticsearch是一个高度可扩展的.开源的.基于 Lucene 的全文搜索和分析引擎.它允许您快速,近实时地存储,搜索和分析大量数据,并支持多租户. Elasticsearch也使用J ...