C 黎明前的巧克力 [* hard]

给定数列 (a),长度为 (n),保证 (n,a_ile 10^6),求有多少种方案选出两个集合 (A,B) 使得两个集合的异或和相同,不能均为空集,答案对 (998244353) 取模。

( m Sol:)

先考虑 (A+B) 的异或和,必然是 (0)

然后考虑 (A+B) 的大小为 (k),那么方案数为 (2^k)

问题等价于求有 (n) 个元素,每个元素可以选/不选,对于 (i=1,2sim n) 求有多少种方案选出 (i) 个数使得权值异或和为 (0)

事实上可以考虑将每个元素视为 ((1+2x^{a_i})) 这样的一个 Xor 多项式,这样的话 ({oplus}_{i=1}^n (1+2x^{a_i})) 中 (x^0) 就是答案了。

然后我们计算 Xor FWT,问题计算的本质上也是卷积结果,不妨考虑 (1+2x^{a_i}) 这个向量 ((F(x))) ?的 Xor_FWT 结果是啥。

我们记得 ( m Xor ~FWT) 的矩阵为 (c(0,0),c(1,0),c(0,1)=1,c(1,1)=-1),所以 FWT 理论告诉我们:

[ extrm{FWT}(F(x))_i=sum_{j=0} f_j imes (-1)^{ extrm{popcount}(i& j)} ]
现在需要计算

[prod extrm{FWT}(1+2x^{a_i})_j=prod igg(sum_k f_k imes (-1)^{ extrm{popcount}(i&k)}igg) ]
另一边,我们注意到似乎 ( extrm{FWT}(F(x))_j) 的值只有 (-1) 和 (3) 两种取值。

同时,我们只需要知道 (prod extrm{FWT}(F(x))_j) 即可

注意到每个位置不是 (-1) 就是 (3),那么假设有 (x) 个 (-1) 那么就有 ((n-x)) 个 (3)

另一边,我们注意到 (sum extrm{FWT}(F(x))= extrm{FWT}(sum F(x))),假设对于 (i) 而言,结果为 (f_i),那么有 (-x+(n-x)3=f_i o 3n-4x=f_i) 于是就可以把 (x) 解出来。

然后就可以快乐的 IFWT 了。

代码极其好写

(Code:)

#include<bits/stdc++.h>
using namespace std ;
#define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
#define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
#define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
#define re register
#define int long long
int gi() {
    char cc = getchar() ; int cn = 0, flus = 1 ;
    while( cc < '0' || cc > '9' ) {  if( cc == '-' ) flus = - flus ; cc = getchar() ; }
    while( cc >= '0' && cc <= '9' )  cn = cn * 10 + cc - '0', cc = getchar() ;
    return cn * flus ;
}
const int N = 2e6 + 5 ;
const int P = 998244353 ; 
const int I = 499122177 ;
int n, m, limit, A[N], c[N], fac[N] ; 
void FWT_xor( int *a, int type ) {
    for( re int k = 1; k < limit; k <<= 1 ) 
    for( re int i = 0; i < limit; i += ( k << 1 ) )
    for( re int j = i; j < i + k; ++ j ) {
        int nx = a[j], ny = a[j + k] ;
        a[j] = ( nx + ny ) % P, a[j + k] = ( nx - ny + P ) % P ; 
        if( !type ) a[j] = a[j] * I % P, a[j + k] = a[j + k] * I % P ; 
    }
}
signed main()
{
    n = gi(), limit = 1, m = 0 ; 
    rep( i, 1, n ) A[i] = gi(), m = max( m, A[i] ), c[A[i]] += 2 ; 
    while( limit <= m ) limit <<= 1 ; fac[0] = 1 ; 
    for( re int i = 1; i <= 2 * n; ++ i ) fac[i] = fac[i - 1] * 3 % P ; 
    c[0] += n, FWT_xor( c, 1 ) ;
    for( re int i = 0; i < limit; ++ i ) {
        int x = ( 3 * n - c[i] + P ) % P ;
        x = x * I % P * I % P, A[i] = fac[n - x] ;
        if( x & 1 ) A[i] = ( P - A[i] ) ;
    }
    FWT_xor( A, 0 ) ;
    printf("%lld
", ( P + A[0] - 1 ) % P ) ;
    return 0 ;
}

UNR2 黎明前的巧克力相关推荐

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

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

  2. UOJ#310. 【UNR #2】黎明前的巧克力

    初见安~这里是传送门:uoj#310. [UNR #2]黎明前的巧克力 题解 这题挺降智的--考虑如果能选出来一个集合使之异或和为0,那么这个集合划分成任意两个集合一定都满足条件. 容易想到形如背包, ...

  3. C. 【UNR #2】黎明前的巧克力

    题意: Evan 和 Lyra 都是聪明可爱的孩子,两年前,Evan 开始为一个被称为UOJ的神秘的OI组织工作,在 Evan 与其他小伙伴的努力下,UOJ不仅成了OI界原创比赛的典范,更是因UR这一 ...

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

    题意: 给出一个数组a,要求把a数组选出两个不相交且不同时为空的子集,满足两个集合中数字的异或和相等. 题解: 考虑dp[i][j]dp[i][j]dp[i][j]表示考虑前iii个数字,且现在两个集 ...

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

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

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

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

  7. UOJ310 黎明前的巧克力 FWT

    传送门 我们要求的是\([x^0]\prod\limits_{i=1}^n (2x^{a_i}+1)\),其中乘积定义为集合对称差卷积. 这个直接做复杂度太高了,考虑优化.注意到在FWT之后,每一个序 ...

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

    1# 正题 题目链接:https://uoj.ac/problem/310 题目大意 给出一个长度为nnn的序列,求有多少种方案找出两个集合S,TS,TS,T使得这两个集合的异或和相等. 1≤n≤10 ...

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

    题目 传送门 to UOJ 题意概要 在给出的 nnn 个自然数中,选出两个集合,其下标不相交(一个元素至多属于一个集合),且两个集合至少有一个非空,使得两个集合内的数字的异或和相等.问方案数,对 9 ...

最新文章

  1. 3d饼图 vue_这是我见过最优雅的Vue图片轮播插件——Vue-Awesome-Swiper
  2. MATLAB-基本语法
  3. java prototype是什么,java设计模式-原型模式(Prototype)
  4. mysql查询时间段内的数据
  5. Idea中Spring整合MyBatis框架中配置文件中对象注入问题解决方案
  6. linux 树型显示文件 tree ls tree 命令
  7. Spring : @Value注解
  8. JavaScript学习(七十二)—严格模式
  9. c++进阶(十八)stack容器和queue容器
  10. (22)Python-builtins-sorted()函数用法
  11. JDK8 有关集合部分常用的语法
  12. 软件工程系组织12级学生到工商学院参加比赛
  13. Linux ---- 安装虚拟机
  14. 安卓问题-第三方相关
  15. COM 组件创建实例失败,原因是出现以下错误: 8001010a解决办法
  16. matlab求任意输入响应曲线,3.6 用Matlab进行动态响应分析
  17. 我用飞桨做了一个菜品图像识别系统
  18. The Open Group正式发布《The Open Group IT4IT参考架构版本 2.1》
  19. 《响应式Web设计实践》一2.2 字体大小
  20. js中text方法是啥意识_JavaScript | 文本节点Text常用方法

热门文章

  1. 将对象的属性值复制到另一个对象中
  2. java1.8日期类_JDK1.8-日期使用
  3. 阿拉伯字母及阿拉伯文排版规则
  4. java写接口给前端_看看人家那后端API接口写得,那叫一个优雅!
  5. matlab选址与GIS选址,ArcGIS入门教程(13)——多条件学校选址分析
  6. 映射、单射、满射、双射
  7. 分享下自己的经历!2020春招四五月份大厂面经 一:(腾讯、网易、斗鱼、富途、美团、快手)
  8. pandas.Series.str.extract 正则提取数据
  9. python opencv入门 光流法(41)
  10. 手机信号不好?真不是套餐原因!4招教你搞定!