HereHereHere

看完题立马联想到黎明前的巧克力
暴力的做法是对每一行做一遍 FWTFWTFWT,这样子是 O(n2mm)O(n2^mm)O(n2mm) 的
发现每个位置的贡献要么是 −ai-a_i−ai​ 要么是 aia_iai​,那么我们可以合起来做 FWTFWTFWT
只需要知道这 2k2^k2k 种正负组合出现多少次就可以了
问题就是出现了多少次,考场始终觉得方程不够,结果发现自己 sb 了
黎明前的巧克力还记得一个位置要么是a1+a2a_1+a_2a1​+a2​,要么是 a1−a2a_1-a_2a1​−a2​,因为 a1a_1a1​ 在位置 0 上
于是我们把每一行的 pi,0p_{i,0}pi,0​ 变成 0,其它的全部异或上 pi,0p_{i,0}pi,0​ 就可以了
假设现在有四种系数 a0+a1+a2,a0+a1−a2,a0−a1+a2,a0−a1−a2a_0+a_1+a_2,a_0+a_1-a_2,a_0-a_1+a_2,a_0-a_1-a_2a0​+a1​+a2​,a0​+a1​−a2​,a0​−a1​+a2​,a0​−a1​−a2​,个数为 a,b,c,da,b,c,da,b,c,d
我们在 a1a_1a1​ 的位置上 +1 做 fwtfwtfwt,就可以得到 a+b−c−da+b-c-da+b−c−d 的值
在 a2a_2a2​ 的位置上 +1 就可以得到 a−b+c−da-b+c-da−b+c−d 的值
发挥人类智慧在 a1⊗a2a_1\otimes a_2a1​⊗a2​ 的位置 +1 就可以得到两个符号的异或,也就是这个式子:
f^s=∑T(−1)∣S∩T∣fT\hat f_s=\sum_{T}(-1)^{|S\cap T|}f_Tf^​s​=∑T​(−1)∣S∩T∣fT​, (−1)∣S∩(a1⊗a2)∣=(−1)∣S∩a1∣(−1)∣S∩a2∣(-1)^{|S\cap (a_1\otimes a_2)|}=(-1)^{|S\cap a_1|}(-1)^{|S\cap a_2|}(−1)∣S∩(a1​⊗a2​)∣=(−1)∣S∩a1​∣(−1)∣S∩a2​∣
那么我们得到了 a−b−c+da-b-c+da−b−c+d 的值
还有一个 a+b+c+d=na+b+c+d=na+b+c+d=n 即可以解出,不能暴力解,巧妙的发现
a+b+c+d=na+b+c+d=na+b+c+d=n
a−b+c−d=Aa-b+c-d=Aa−b+c−d=A
a+b−c−d=Ba+b-c-d=Ba+b−c−d=B
a−b−c+d=Ca-b-c+d=Ca−b−c+d=C
把得到的 ifwtifwtifwt 回去就可以得到原来的
那么复杂度就是 O(kn+2k+m(k+m))O(kn+2^{k+m}(k+m))O(kn+2k+m(k+m))


#include<bits/stdc++.h>
#define cs const
using namespace std;
typedef long long ll;
int read(){ll cnt = 0, f = 1; char ch = 0;while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();return cnt * f;
}
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int ksm(int a, int b){ int ans = 1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans = mul(ans, a); return ans; }
void Add(int &a, int b){ a = add(a, b); }
void Dec(int &a, int b){ a = dec(a, b); }
void Mul(int &a, int b){ a = mul(a, b); }
cs int N = 1e6 + 50, K = 10, M = 1 << 9;
int n, m, k, Sm, Sk, a[K], p[N][K];
#define poly vector<int>
poly vl[M];
void FWT(poly &a, int S, int typ){for(int i = 1; i < S; i <<= 1)for(int j = 0; j < S; j += (i<<1))for(int k = 0; k < i; k++){int x = a[k + j], y = a[k + j + i];a[k + j] = add(x, y); a[k + j + i] = dec(x, y);}if(typ == -1)for(int i = 0, iv = ksm(S,Mod-2); i < S; i++) Mul(a[i], iv);
}
int main(){n = read(), m = read(), k = read();Sm = 1 << m;Sk = 1 << k - 1;for(int i = 0; i < k; i++) a[i] = read();int tag = 0;for(int i = 1; i <= n; i++){p[i][0] = read(); tag ^= p[i][0];for(int j = 1; j < k; j++) p[i][j] = read(), p[i][j] ^= p[i][0];}for(int S = 0; S < Sk; S++){vl[S].resize(n + 1);vl[S][0] = 1; vl[S][1] = a[0];for(int j = 1; j < k; j++) (S >> (j - 1) & 1) ? Dec(vl[S][1], a[j]) : Add(vl[S][1], a[j]);for(int j = 2; j <= n; j++) vl[S][j] = mul(vl[S][1],vl[S][j-1]);}static poly f[M];for(int S = 0; S < Sk; S++){f[S].resize(Sm);for(int i = 1; i <= n; i++){int x = 0;for(int j = 1; j < k; j++) if(S >> (j - 1) & 1) x ^= p[i][j];++f[S][x];} FWT(f[S], Sm, 1);}poly F(Sm, 1);for(int i = 0; i < Sm; i++){poly G(Sk, 0);for(int j = 0; j < Sk; j++) G[j] = f[j][i];FWT(G, Sk, -1);for(int j = 0; j < Sk; j++) Mul(F[i], vl[j][G[j]]);}FWT(F, Sm, -1);for(int i = 0; i < Sm; i++) cout << F[i ^ tag] << " ";return 0;
}

【省选模拟】西行(FWT)相关推荐

  1. 电力职称计算机多选,【2017年整理】职称计算机考试Office多选模拟题及答案.doc...

    [2017年整理]职称计算机考试Office多选模拟题及答案 时代学习社区(/)是一个专门提供计算机类.外语类.资格类.学历类,会计类.建筑类.医学类等教育信息服务的教育学习交流社区.希望大家本着人人 ...

  2. 2017 04 04 省选模拟

    该场考试(或者说竞赛)题目来自北京省选模拟赛. 题目简单,但我们太菜. 第一题, 题意:一个N个点的环,每个点一个权值,求问最小的将这个环划分成K个区域的最小方差. 评价:出题人二合一,差评. 题解: ...

  3. 省选模拟赛记录(越往下越新哦~~~)

    LOG 模拟赛 第一次见尼玛这么给数据范围的-- 开考有点困,迷迷糊糊看完了三道题,真的是像老吕说的那样,一道都不会-- 思考T1,感觉有点感觉,但是太困了,就先码了暴力,发现打表可以50分,于是就大 ...

  4. [2021.1.17多校省选模拟4]T1(莫比乌斯反演/组合数学/枚举倍数)

    [2021.1.17多校省选模拟4]T1 一般人都会想着去枚举直线的斜率,但是枚举斜率之后就会产生多条直线,并且这些直线的长度不一,难以快速求解,所以我们考虑换一种方法枚举. 枚举最远点对的横纵坐标之 ...

  5. [2021.1.13多校省选模拟2]T1(动态规划/轮廓线dp)

    [2021.1.13多校省选模拟2]T1 一个经典的轮廓线dp,可以发现一定可以找到一条轮廓将这个图形分开,然后使得左半部分由左边处理,右半部分由右边处理,然后我们只需要处理这个折线即可,具体实现需要 ...

  6. [2021.1.31多校省选模拟12]随机变换的子串(线段树维护分治/字符串/自动机思想)

    [2021.1.31多校省选模拟12]随机变换的子串 对于这三种操作,我们惊奇地发现有这样的性质,所有长度大于4的字符串都可以通过变换变为长度小于等于4的字符串,那么查询本质不同的字符串我们只需要处理 ...

  7. A. [2021.1.29多校省选模拟11]最大公约数(杜教筛/数论)

    A. [2021.1.29多校省选模拟11]最大公约数 这是一个杜教筛的经典题目,最后我们只需要筛一下1∗xμ(x)1*x\mu(x)1∗xμ(x)这个函数的前缀和即可,然后看到有111这个函数,我们 ...

  8. [2021.1.27多校省选模拟10]跑步(线段树合并)

    [2021.1.27多校省选模拟10]跑步 经典的树上启发式合并题目,维护对应子树的从当前点到子树内一个节点这个链待定,其他部分已经确定的方案数,这个东西按照对应点到根节点的路径点权和为下标存在一个权 ...

  9. [2021.1.27多校省选模拟10]染色(min-max容斥/二项式反演)

    [2021.1.27多校省选模拟10]染色 突然发现我对概率期望的理解不是很好... 部分分1:可以直接进行状压dp,然后按照题意模拟即可. 部分分2:首先可以发现这个问题是min_max容斥形式,然 ...

  10. 省选模拟赛2022/3/23

    省选模拟赛2022/3/23 比赛时间安排 赛后总结反思 与正解的差距 T1 T2 T3 比赛时间安排 7.30-7.40 t1 n<=10,全排列一下跳叶子结点的顺序暴力搞 t2 题意感觉好复 ...

最新文章

  1. [JS] for-each和map()的区别
  2. MYSQL编译参数详解
  3. Django 框架入门篇(安装与创建项目)
  4. v-for中为什么要有key属性
  5. 并行编程中的“锁”难题
  6. 「万字图文」史上最姨母级Java继承详解
  7. 浅谈Nginx服务器的内部核心架构设计
  8. HAPPY_TOGETHER_WEEK15_ENJOY
  9. ssl初一组周六模拟赛【2018.4.7】
  10. ethereumjs/ethereumjs-common-3-test
  11. leetcode - First Missing Positive
  12. 北美程序员面试常见问题
  13. java连接oracle sid_jdbc连接数据库使用sid和service_name的区别
  14. 2019年上半年 系统分析师 论文 真题
  15. 骁龙cpu linux内核,高通骁龙888 SoC在Linux 5.12内核才被支持,以往怎么兼容的?
  16. 数据拟合之Excel篇
  17. 基于Android的个人时间管理设计与开发
  18. 英文构词词根表---不定式+过去式+过去分词
  19. 人体红外传感器HC-SR501特点及使用介绍
  20. python练习_邮件定时收取处理附件后发送结果

热门文章

  1. 当部分地区电信运营商劫持页面,如何识别及解决
  2. 英语四级词汇:四级词组百词大关
  3. 使用python下载网易云课堂中Andrew Ng的机器学习课程
  4. “中关村黑马程序员训练营”练习题(二)
  5. JPA的@Query用法
  6. Silverlight开发MMORPG游戏研讨(4):用一个定时器实现多个不同帧频的动画
  7. Spring Aop(四)——基于Aspectj注解的Advice介绍
  8. 四门轿跑 标致发布Exalt概念车设计图
  9. 【我的OpenGL学习进阶之旅】解决着色器语法错误:The shader uses varying u_Color, but previous shader does not write to it
  10. 【共享经济】为什么共享衣橱用的是B2C而不是C2C模式?