NFLSOJ 1072 - 【2021 六校联合训练 NOIP #1】异或(FWT+插值)
一道非常不错的 FWT+插值的题 %%%%%%%%%%%%
还是那句话,反正非六校的看不到题对吧(((
方便起见在下文中设 \(n=2^d\)。
首先很明显的一点是这题涉及两个维度:异或和与选出的元素的个数。因此考虑像子集卷积那样建立一个二元生成函数表示这个东西,具体来说我们定义一个幂级数 \(F\) 形如 \(\sum\limits_{n\ge 0}\sum\limits_{m\ge 0}f_{n,m}x^ny^m\),并定义两个幂级数 \(F,G\) 的乘法得到的幂级数 \(H\) 满足 \(H_{i,j}=\sum\limits_{p\oplus q=i}\sum\limits_{r+s=j}F_{p,r}G_{q,s}\),那么这样我们相当于将所有 \(F_i(x,y)=1+a_ix^{i}y\) 乘起来,具体来说,设 \(G=\prod\limits_{i=0}^{n-1}1+a_ix^iy\),那么 \(res_i=\sum\limits_{j=0}^{n-1}[x^jy^i]G·b_j\),或者如果我们将答案的生成函数视作一个整体 \(R(x)\),那么 \(R(x)=\sum\limits_{j=0}^{n-1}[x^j]G·b_j\)。
考虑怎么求解 \(G\),按照子集卷积的套路我们考虑定某个东西为主元,在这题中我们考虑定 \(x\) 为主元,那么所有集合幂级数 \(F\) 都可以写成 \(\sum\limits_{i=0}^{n-1}F_i(y)x^i\),其中 \(F_i(y)\) 为某个关于 \(y\) 的多项式。这样一来两个幂级数做乘法则相当于对两个以形式幂级数为系数的集合幂级数做 xor 卷积,因此考虑将每个集合幂级数都 FWTxor 一遍,对应项相乘再 IFWTxor 回去即可得到上文中所说的 \(G\)。具体来说,显然 \(\text{FWT}(F_i(x,y))=\sum\limits_{j=0}^{n-1}(1+(-1)^{\text{builtin\_popcount}(i\&j)}a_iy)·x^j\),因此对应项相乘就有 \(\text{FWT}(G)=\sum\limits_{j=0}^{n-1}(\prod\limits_{i=0}^{n-1}(1+(-1)^{\text{builtin\_popcount}(i\&j)}a_iy))·x^j\),再 IFWTxor 回去即可算出真正的 \(G\),进而求出答案。
但是这样暴力操作复杂度还是会出问题,考虑优化。首先注意到 IFWTxor 是个线性变换,因此我们考虑不将 IFWTxor 作用与 \(\text{FWT}(G)\),instead 我们将其作用于 \(b\),也就是说答案的多项式 \(R(x)\) 可以写成 \(\sum\limits_{j=0}^{n-1}[x^j]G·b'_j\),其中 \(b’=\text{IFWT}(b)\),即
\]
考虑怎么求解后面那个东西,我们考虑用类似于 FWTxor 的东西求解。考虑分治,具体来说当我们求一排这样的多项式的乘积时候将序列分成左右两部分 \(F_1(x),F_2(x)\),那么合并时候,对于所有 \(i\in[0,\dfrac{n}{2})\),仿照 FWTxor 的套路则有 \(F_i(x)=F_{1,i}(x)F_{2,i}(x),F_{i+n/2}(x)=F_{1,i}(x)F_{2,i}(-x)\),如果直接莽个 MTT 上去复杂度是 \(d^24^d\) 的,并且自带大常数,无法通过,不过注意到最后答案序列也是一个 \(n\) 次多项式,因此考虑插值。具体来说,我们使用上述方法求出以上 \(n\) 个多项式在 \(-\dfrac{n}{2},-\dfrac{n}{2}+1,\cdots,0,\cdots,\dfrac{n}{2}-1,\dfrac{n}{2}\) 处的点值,这样可以在 \(\mathcal O(n^2)\) 时间内计算出 \(R(x)\) 在 \(-\dfrac{n}{2},-\dfrac{n}{2}+1,\cdots,0,\cdots,\dfrac{n}{2}-1,\dfrac{n}{2}\),再一遍拉格朗日插值即可得到 \(R(x)\) 的系数。
时间复杂度 \(4^d·d\)
const int MAXN=2052;
const int MOD=1e9+7;
const int INV2=5e8+4;
int n,d,a[MAXN+5],b[MAXN+5],sum[MAXN+5];
int val[MAXN+5][MAXN+5],tmp[MAXN+5][MAXN+5];
void FWTxor(int *a,int len,int type){
for(int i=2;i<=len;i<<=1)
for(int j=0;j<len;j+=i)
for(int k=0;k<(i>>1);k++){
int X=a[j+k],Y=a[(i>>1)+j+k];
a[j+k]=1ll*type*(X+Y)%MOD;
a[(i>>1)+j+k]=1ll*type*(X-Y+MOD)%MOD;
}
}
int prd[MAXN+5],dv[MAXN+5];
int inv[MAXN+5],ss[MAXN+5];
int getinv(int x){return (x<0)?(MOD-inv[-x]):inv[x];}
void init_fac(int n){
for(int i=(inv[0]=inv[1]=1)+1;i<=n;i++) inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
int main(){
scanf("%d",&d);n=1<<d;init_fac(MAXN);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
FWTxor(b,n,INV2);
for(int i=0;i<n;i++) for(int j=-n>>1;j<=(n>>1);j++)
val[i][j+(n>>1)]=(1+1ll*a[i]*j%MOD+MOD)%MOD;
for(int i=2;i<=n;i<<=1){
memset(tmp,0,sizeof(tmp));
for(int j=0;j<n;j+=i)
for(int k=0;k<(i>>1);k++)
for(int x=-n>>1;x<=(n>>1);x++){
tmp[j+k][x+(n>>1)]=1ll*val[j+k][x+(n>>1)]*val[(i>>1)+j+k][x+(n>>1)]%MOD;
tmp[(i>>1)+j+k][x+(n>>1)]=1ll*val[j+k][x+(n>>1)]*val[(i>>1)+j+k][-x+(n>>1)]%MOD;
}
for(int j=0;j<n;j++) for(int k=0;k<=n;k++)
val[j][k]=tmp[j][k];
}
for(int j=0;j<n;j++) for(int k=0;k<=n;k++)
sum[k]=(sum[k]+1ll*val[j][k]*b[j])%MOD;
// for(int k=0;k<=n;k++) printf("%d%c",sum[k]," \n"[k==n]);
prd[0]=1;
for(int x=-n>>1;x<=(n>>1);x++){
for(int i=n+1;i;i--)
prd[i]=(0ll+prd[i-1]+1ll*prd[i]*x%MOD+MOD)%MOD;
prd[0]=1ll*prd[0]*(x+MOD)%MOD;
}
// for(int i=0;i<=n+1;i++) printf("%d%c",prd[i]," \n"[i==n+1]);
for(int v=-n>>1;v<=(n>>1);v++){
memset(dv,0,sizeof(dv));
for(int i=n;~i;i--)
dv[i]=(0ll+prd[i+1]-1ll*(MOD-v)*dv[i+1]%MOD+MOD)%MOD;
int mul=1;
for(int x=-n>>1;x<=(n>>1);x++) if(v^x)
mul=1ll*mul*getinv(v-x)%MOD;
mul=1ll*mul*sum[v+(n>>1)]%MOD;
// printf("%d %d\n",v,mul);
// for(int i=0;i<=n;i++) printf("%d%c",dv[i]," \n"[i==n]);
for(int i=0;i<=n;i++) ss[i]=(ss[i]+1ll*dv[i]*mul)%MOD;
} for(int i=1;i<=n;i++) printf("%d%c",ss[i]," \n"[i==n]);
return 0;
}
/*
2
1 2 3 4
0 1 2 3
*/
NFLSOJ 1072 - 【2021 六校联合训练 NOIP #1】异或(FWT+插值)的更多相关文章
- NFLSOJ 1060 - 【2021 六校联合训练 NOI #40】白玉楼今天的饭(子集 ln)
由于 NFLSOJ 题面上啥也没有就把题意贴这儿了( 没事儿,反正是上赛季的题,你们非六校学生看了就看了,况且看了你们也没地方交就是了 题意: 给你一张 \(n\) 个点 \(m\) 条边的图 \(G ...
- 题解 nflsoj553 【六校联合训练 省选 #10】飞
题目链接 我们称"简要题意"给出的三个要求分别为"条件1","条件2","条件3". 条件3长得比较丑,考虑转化一下.把 ...
- 题解 nflsoj550 【六校联合训练 省选 #9】序列
题目链接 以下把值域(题面里的\(lim\))记做\(m\). 考虑求\(k\)的答案.考虑每个位置对答案的贡献,枚举位置\(i\),再枚举\(a[i]\)的值\(x\).设: \[ F(k)=\su ...
- 题解 nflsoj489 【六校联合训练 CSP #15】小D与随机
题目链接 考虑枚举好点的集合.此时要考虑的问题是如何填入\(1\sim n\)这些数使得恰好我们枚举到的这些点是好点,即:求出有多少种合法的填数方案. \(1\)号点一定是好点.那么除\(1\)号点外 ...
- HDU 5358(2015多校联合训练赛第六场1006) First One (区间合并+常数优化)
pid=5358">HDU 5358 题意: 求∑i=1n∑j=in(⌊log2S(i,j)⌋+1)∗(i+j). 思路: S(i,j) < 10^10 & ...
- 2017多校联合训练2—HDU6054--Is Derek lying?(思维题)
Is Derek lying? Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- 2017ACM暑期多校联合训练 - Team 7 1010 HDU 6129 Just do it (找规律)
题目链接 Problem Description There is a nonnegative integer sequence a1...n of length n. HazelFan wants ...
- 2016多校联合训练4 F - Substring 后缀数组
Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...
- 2014 多校联合训练赛6 Fighting the Landlords
本场比赛的三个水题之一,题意是两个玩家每人都持有一手牌,问第一个玩家是否有一种出牌方法使得在第一回和对方无牌可出.直接模拟即可,注意一次出完的情况,一开始没主意,wa了一发. #include< ...
随机推荐
- 按键检测GPIO输入
1. 项目 通过按键控制开关LED灯,按下按键灯亮,再按一下灯灭. 2. 代码 mian.c #include "stm32f10x.h" //相当于51单片机中的 #includ ...
- Python设置Excel样式
前面已经详细讲解过使用Python对Excel表格进行读.写操作,本文主要讲解下使用Python设置Excel表格的样式. 深入学习请参考openpyxl官方文档: https://openpyxl. ...
- vue3.x非兼容的变更
走马观花似的看看从vue2.x开始到vue3.x的一些非兼容性的变更,这样在将来升级过程中遇到那些奇奇怪怪的不能用的时候,就会很容易解决啦. 全局 API 全局 Vue API 已更改为使用应用程序实 ...
- Convolutional Neural Network-week2编程题2(Residual Networks)
1. Residual Networks(残差网络) 残差网络 就是为了解决深网络的难以训练的问题的. In this assignment, you will: Implement the basi ...
- [no_code]团队贡献分分配规则
项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 团队贡献分分配规则 我们在这个课程的目标是 远程协同工作,采用最新技术开发软件 这个作 ...
- 运维常用python库&模块
sutil:是一个跨平台库(https://github.com/giampaolo/psutil)能够实现获取系统运行的进程和系统利用率(内存,CPU,磁盘,网络等),主要用于系统监控,分析和系统资 ...
- 2021.8.8考试总结[NOIP模拟33]
T1 Hunter 考场上一看期望直接状压拿了$45pts$跑了.结果正解只用$4$行? 把问题转化为一号猎人之前死的猎人数的期望加一. 期望的线性性. 对每个猎人$i$,$w_i+w_1$种情况中有 ...
- 攻防世界 web2.robots
输入ip/robots.txt,显示出了flag目录,直接访问.
- 力扣 - 剑指 Offer 57 - II. 和为s的连续正数序列
题目 剑指 Offer 57 - II. 和为s的连续正数序列 思路1(双指针/滑动窗口) 所谓滑动窗口,就是需要我们从一个序列中找到某些连续的子序列,我们可以使用两个for循环来遍历查找,但是未免效 ...
- 双栈排序 牛客网 程序员面试金典 C++ Python
双栈排序 牛客网 程序员面试金典 C++ Python 题目描述 请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中. ...