题意

给出 \(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)\) 的。

代码

  1. #include <bits/stdc++.h>
  2. #define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
  3. #define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
  4. #define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
  5. #define Set(a, v) memset(a, v, sizeof(a))
  6. #define Cpy(a, b) memcpy(a, b, sizeof(a))
  7. #define debug(x) cout << #x << ": " << (x) << endl
  8. using namespace std;
  9. typedef long long ll;
  10. template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
  11. template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
  12. inline int read() {
  13. int x(0), sgn(1); char ch(getchar());
  14. for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
  15. for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
  16. return x * sgn;
  17. }
  18. void File() {
  19. #ifdef zjp_shadow
  20. freopen ("310.in", "r", stdin);
  21. freopen ("310.out", "w", stdout);
  22. #endif
  23. }
  24. const int len = 1 << 20, N = len << 1, Mod = 998244353, inv2 = (Mod + 1) / 2;
  25. inline int fpm(int x, int power) {
  26. int res = 1;
  27. for (; power; power >>= 1, x = 1ll * x * x % Mod)
  28. if (power & 1) res = 1ll * res * x % Mod;
  29. return res;
  30. }
  31. void FWT(ll *P, int opt) {
  32. for (int i = 2, p = 1; i <= len; p = i, i <<= 1)
  33. for (int j = 0; j < len; j += i) Rep (k, p) {
  34. ll u = P[j + k], v = P[j + k + p];
  35. P[j + k] = u + v; P[j + k + p] = u - v;
  36. }
  37. if (!~opt) {
  38. int inv = fpm(len, Mod - 2);
  39. Rep (i, len) P[i] = 1ll * (Mod + P[i] % Mod) * inv % Mod;
  40. }
  41. }
  42. ll A[N], pow3[N];
  43. int main () {
  44. File();
  45. int n = read();
  46. pow3[0] = 1;
  47. For (i, 1, n)
  48. ++ A[0], A[read()] += 2, pow3[i] = pow3[i - 1] * 3ll % Mod;
  49. FWT(A, 1);
  50. Rep (i, len) {
  51. int x = (3 * n - A[i]) / 4;
  52. A[i] = (Mod + (x & 1 ? -1 : 1) * pow3[n - x]) % Mod;
  53. }
  54. FWT(A, -1);
  55. printf ("%lld\n", (A[0] + Mod - 1) % Mod);
  56. return 0;
  57. }

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. 逛csdn看见的一个知识阶梯,感觉不错

    逛csdn看见的一个知识阶梯,感觉不错: 计算机组成原理 →  DOS命令 → 汇编语言 → C语言(不包括C++).代码书写规范 → 数据结构.编译原理.操作系统 → 计算机网络.数据库原理.正则表 ...

  2. CPP笔记_函数返回局部变量

    本篇笔记记录的是关于返回函数中的局部值. 我们知道,在函数中创建的局部变量会随着函数的调用过程的结束,也即其对应函数栈帧的清除,而结束其生命周期.那么,如果我们把这个局部变量返回,就有可能存在该变量对 ...

  3. Docker Data Center系列(二)- UCP安装指南

    本系列文章演示如何搭建一个mini的云平台和DevOps实践环境. 基于这套实践环境,可以部署微服务架构的应用栈,演练提升DevOps实践能力. 1 系统要求 1.1 硬件和软件要求 Linux内核版 ...

  4. Github速度慢的解决方法

    首先ping一下github.global.ssl.fastly.net 得到相应的ip,例如我现在ping的ip是151.101.41.194 151.101.41.194 github.globa ...

  5. C#-事件event

    目录 1. 简介 2.实际案例 2.1实际案例1 2.2实际案例2--带有参数的事件 3.标准事件的用法 3.1通过扩展EventArgs来传递数据 3.2代码实例 1. 简介 事件是一种类型安全的委 ...

  6. Failed to initialize component [org.apache.catalina.webresources.JarResource

    去本地仓库里删除掉对应出错的jar包,然后回到pom里面加个空行 让他重新下载(最好把maven仓库全部都删了 重新下载一次 ) 先备份 在复制回来 完美解决

  7. 系统重装助手教你如何在Microsoft Edge中恢复“关闭所有选项卡”警告

    在Microsoft Edge中,当您打开多个选项卡时,浏览器将显示“您要关闭所有选项卡吗?” 警告,以防止您意外关闭重要标签. 通常,在没有第二个想法的情况下,您会立即禁用此功能,检查提示中的“始终 ...

  8. 5.3Python数据处理篇之Sympy系列(三)---简化操作

    目录 5.3简化操作 目录 前言 (一)有理数与多项式的简化 1.最简化-simplify() 2.展开-expand() 3.提公因式-factor() 4.合并同类项-ceiling() 5.简化 ...

  9. python中创建虚拟环境

    # virtualenv 虚拟环境安装 pip install virtualenv # 创建虚拟环境        virtualenv [虚拟环境名称] # 进入虚拟环境 windows : 进入 ...

  10. 【笔记】基于Python的数字图像处理

    [博客导航] [Python相关] 前言 基于Python的数字图像处理,离不开相关处理的第三方库函数.搜索网络资源,列出如下资源链接. Python图像处理库到底用哪家 python计算机视觉编程— ...