题解:mex times mex(省选模拟赛 T2)
前言
题目链接:here.
这是一个 T1 读错题刚 T2 导致垫底的可怜人的博客。
思路分析
首先这个柿子一看就是魔改的 FWT 的卷积。
考虑分治处理。
对于当前分治层 ,考虑求出 。
如果我们将 三个序列都分为 段,分别记为 ,那么我们需要通过若干次卷积用 求出 。
因为 FWT 是线性变换,大胆猜测,我们题目中要求的卷积也是线性变换。
如果有这个性质就好做了,我们只需要构造若干参数,使得用 中的若干向量卷积能够凑出 即可。
考虑不要脸地用 和 的递归关系构造参数。
当 时,
当 时,,,
不难构造出我们想要的参数,也就是:
现在分析复杂度。
设 表示对长度为 的两个序列做卷积的复杂度,那么有递推式:
大概就是一个 罢!
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,k;
inline vector<long long> mex(vector<long long> &a,vector<long long> &b){
int n=a.size();
vector<long long> c(n,1);
if(n==1){
c[0]=a[0]*b[0];
return c;
}
n/=3;
vector<long long> A(n,1),B(n,1);
for(int i=0;i<n;i++){
A[i]=a[i+n*2];
B[i]=b[i+n*2];
}
vector<long long> d1=mex(A,B);//a2*b2
for(register int i=0;i<n;i++){
A[i]+=a[i];
B[i]+=b[i];
}
vector<long long> d2=mex(A,B);//(a0+a2)*(b0+b2)
for(register int i=0;i<n;i++){
A[i]+=a[i+n];
B[i]+=b[i+n];
}
vector<long long> d3=mex(A,B);//(a0+a1+a2)*(b0+b1+b2)
for(register int i=0;i<n;i++){
A[i]-=a[i];
B[i]-=b[i];
}
vector<long long> d4=mex(A,B);//(a1+a2)*(b1+b2)
for(register int i=0;i<n;i++){
c[i]=d4[i];
c[i+n]=d2[i]-d1[i];
c[i+n*2]=d3[i]-d4[i]-d2[i]+d1[i];
}
return c;
}
signed main(){
freopen("mex.in","r",stdin);
freopen("mex.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>k;
n=1;
for(int i=1;i<=k;i++) n*=3;
vector<long long> a(n,1),b(n,1),c(n,1);
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
cin>>b[i];
}
c=mex(a,b);
for(int i=0;i<n;i++){
cout<<c[i]<<' ';
}
return 0;
}
本文作者:Kenma
本文链接:https://www.cnblogs.com/Kenma/p/18706548
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步