题意

给出 \(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. 面板JPanel,滚动面板JScrollPane,文本域JTextArea

    [面板JPanel] 面板就是一个容器 每一个容器都可以有一个自己的独立的布局和组件,这些容器之间也不会互相干扰 //导入Java类 import javax.swing.*; import java ...

  2. HALCON学习笔记

    2019-2-2: 硬件选型--->镜头光源相机选型第一讲.avi: 高斯公式:1/u+1/v=1/f  u:物距  v:像距 f:焦距 线放大倍率:像高/物高  或者 像距/物距 镜头需要掌握 ...

  3. macOS 安装 Java (Homebrew)

    macOS 安装多个 Java 版本 Homebrew 是 macOS 下的一个非常好用的包管理工具, caskroom 则是基于 Homebrew 构建的一个强大的应用程序管理器. Homebrew ...

  4. Unity2018 Open C# Project Error

    错误日志 升级到Unity2018之后,使用 Open C# Project 打开VS工程,出现报错,无法启动VS. 错误日志如下: ArgumentException: Value does not ...

  5. Linux DNS服务配置

    主.从域名服务器配置 一.实验环境 主域名服务器:ns1.topsec.com,192.168.120.119 从域名服务器:ns2.topsec.com,192.168.120.120 二.实验步骤 ...

  6. Mysql数据库基础学习笔记

    Mysql数据库基础学习笔记 1.mysql查看当前登录的账户名以及数据库 一.单表查询 1.创建数据库yuzly,创建表fruits 创建表 ) ) ,) NOT NULL,PRIMARY KEY( ...

  7. spark-2.4.0-hadoop2.7-简单操作

    1. 说明 本文基于:spark-2.4.0-hadoop2.7-高可用(HA)安装部署 2. 启动Spark Shell 在任意一台有spark的机器上执行 # --master spark://m ...

  8. SQLServer之修改CHECK约束

    使用SSMS数据库管理工具修改CHECK约束 1.打开数据库,选择数据表->右键点击->选择设计(或者展开约束,选择约束,右键点击,选择修改,后面步骤相同). 2.选择要修改的数据列-&g ...

  9. eclipse弃坑记第一篇之在idea上配置Tomcat环境并创建Javaweb项目的详细步骤原创

    IntelliJ IDEA是一款功能强大的开发工具,在代码自动提示.重构.J2EE支持.各类版本工具(如git.svn.github).maven等方面都有很好的应用. IntelliJ IDEA有免 ...

  10. luffy项目后台drf搭建(1)

    一 进入虚拟环境 打开crm,输入命令 workon luffy 虚拟环境使用文档 二 安装基本类库 pip install django pip install PymySQL pip instal ...