(以下以$B$为进制,$m$为幂次,$n=B^{m}$)

定义$\oplus$为$k$进制下不进位加法,$\otimes$为$\oplus$卷积

令$f_{i,j}$表示前$i$个数的$\oplus$之和为$j$的子序列数,再令$g_{i,j}=[j=0]+[j=a_{i}]$($a_{i}$为给定序列),则$f_{i}=f_{i-1}\otimes g_{i}$

类似uoj272,但以该题复杂度计算时间复杂度显然是不对的

根据$g_{i,j}$的式子,不难发现将其做了DFT后的结果显然恰好就是矩阵$A$的第0行加第$a_{i}$行

直接考虑最终将每一个$g_{i}$的DFT对应位置相乘后第$j$个位置的值,即$ans_{j}=\prod_{i=1}^{n}(A_{0,j}+A_{a_{i},j})$

不难发现$A_{i,j}=\omega^{k}$(指存在$k$,其中$0\le k<B$),我们如果能知道$A_{a_{i},j}$中每一个$k$出现了多少次,再使用快速幂来计算,就可以做到$o(B\log_{2}n)$的复杂度了

更具体的,用$f_{i,j}$表示有多少个$k$满足$A_{a_{k},i}=\omega^{j}$,答案即$ans_{j}=\prod_{i=0}^{B-1}(1+\omega^{i})^{f_{j,i}}$($A_{0,j}=1$)

如何求出$f_{i,j}$,其并不容易递推,考虑这样一个构造:对于每一个$i$,求出$f_{i}$这个长度为$B$的序列DFT的结果,再用IDFT即求出$f_{i,j}$

考虑这个DFT结果的第$k$个数,即$\sum_{l=0}^{B-1}f_{i,l}A_{l,k}=\sum_{l=0}^{B-1}f_{i,l}(\omega^{l})^{k}=\sum_{l=0}^{n-1}(A_{a_{l},i})^{k}$

再构造一个$C_{i}=\sum_{j=0}^{n-1}[a_{j}=i]$,那么对$C$做DFT后的第$i$项即为$\sum_{j=0}^{n-1}C_{j}A_{j,i}=\sum_{j=0}^{n-1}A_{a_{j},i}$

其实这两个式子很接近,只需要让每一个$A_{i,j}$都变为其$k$次幂即可

注意到我们能快速计算DFT依赖于第二个性质($A_{i,j}=A_{\lfloor\frac{i}{B}\rfloor,\lfloor\frac{j}{B}\rfloor}A_{i\ mod\ B,j\ mod\ B}$),而在这个性质下,让每一个$A_{i,j}$都变为其$k$次幂等价于构造$A$左上角的$B\times B$的部分为$A_{i,j}=\omega^{ijk}$

具体来说,分为以下四个步骤:

1.对$C$做$B$次DFT,每一次DFT的$A$矩阵不同,第$k(0\le k<B)$次DFT的$A_{i,j}=\omega^{ijk}(0\le i,j<B)$,这里的时间复杂度是$o(mB^{m+4})$(由于两数相乘复杂度也为$o(B^{2})$,一次DFT复杂度为$o(mB^{m+3})$)

2.对于第一步中第$i$次DFT结果的第$j$项,恰好就是$f_{j}$(这是一个长为$B$的数列)做DFT后的第$i$项,换言之我们得到了每一个$f_{j}$做DFT后的结果,做$n$次$B^{4}$的IDFT即可,复杂度为$o(B^{m+4})$

3.得到$f_{i,j}$后,直接根据$ans_{j}=\prod_{i=0}^{B-1}(1+\omega^{i})^{f_{j,i}}$计算出$ans_{j}$,通过快速幂来优化,那么求一个$ans_{j}$的时间复杂度为$o(B^{3}\log_{2}n)$,总复杂度即$o(B^{m+3}\log_{2}n)$

4.求出$ans_{j}$再做一次IDFT即为答案,时间复杂度为$o(mB^{m+3})$

最终总复杂度为$o((m+\log_{2}n)B^{m+4})$,可以通过

另外关于数值的表示,在平常递归时先使用$\sum_{i=0}^{B-1}a_{i}\omega^{i}$来表示,根据$\omega^{B}=1$可以对其封闭运算,当我们可以证明某一个数为实数且需要得到该值时,通过如下方式降幂,然后$\omega^{0}$系数即为答案

降幂的需要对$B$分类:

1.若$B=5$,将$\omega^{4}$利用$\sum_{i=0}^{4}\omega^{i}=\frac{1-\omega^{5}}{1-\omega}=0$来降幂

2.若$B=6$,根据$\omega^{3}=-1$来降幂,首先得到$\omega^{i}=-\omega^{i-\frac{B}{2}}$来将$i$次项($\frac{B}{2}\le i<B$)降幂,再利用$\sum_{i=0}^{2}(-\omega)^{i}=\frac{1-(-\omega)^{3}}{1+\omega}=0$来降$\omega^{2}$

关于这个降幂的正确性(也就是之后高次项不能将虚数部分抵消)不会证,但可以发现其等价于不能再次进行降幂,之后(观察)发现找不到继续降的方式,即合法

(注意输入是$B$进制)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define M 7
5 #define maxB 6
6 #define mod 998244353
7 int n,m,x,B,base[N][M];
8 struct Complex{
9 int a[maxB];
10 Complex(){
11 memset(a,0,sizeof(a));
12 }
13 Complex(int x){
14 memset(a,0,sizeof(a));
15 a[0]=x;
16 }
17 Complex(int x,int y){
18 memset(a,0,sizeof(a));
19 a[0]=x,a[1]=y;
20 }
21 Complex operator + (const Complex &k)const{
22 Complex o;
23 for(int i=0;i<B;i++)o.a[i]=(a[i]+k.a[i])%mod;
24 return o;
25 }
26 Complex operator * (const Complex &k)const{
27 Complex o;
28 for(int i=0;i<B;i++)
29 for(int j=0;j<B;j++)o.a[(i+j)%B]=(o.a[(i+j)%B]+1LL*a[i]*k.a[j])%mod;
30 return o;
31 }
32 int get(){
33 if (B==5)return (a[0]-a[4]+mod)%mod;
34 return ((a[0]-a[3]+mod)%mod-(a[2]-a[5]+mod)%mod+mod)%mod;
35 }
36 }inv,A[maxB][maxB],AA[maxB][maxB],invA[maxB][maxB],a[N],b[maxB][N],f[N][maxB];
37 int read(){
38 int x=0;
39 char c=getchar();
40 while ((c<'0')||(c>'9'))c=getchar();
41 while ((c>='0')&&(c<='9')){
42 x=x*B+c-'0';
43 c=getchar();
44 }
45 return x;
46 }
47 Complex pow(Complex n,int m){
48 Complex s=n,ans=Complex(1);
49 while (m){
50 if (m&1)ans=ans*s;
51 s=s*s;
52 m>>=1;
53 }
54 return ans;
55 }
56 void DFT(Complex *a){
57 Complex aa[B];
58 for(int i=0,s=1;i<m;i++,s*=B)
59 for(int j=0;j<n;j++)
60 if (!base[j][i]){
61 for(int k=0;k<B;k++)aa[k]=Complex();
62 for(int k=0;k<B;k++)
63 for(int l=0;l<B;l++)aa[k]=aa[k]+a[j+l*s]*A[l][k];
64 for(int k=0;k<B;k++)a[j+k*s]=aa[k];
65 }
66 }
67 void IDFT(Complex *a){
68 Complex aa[B];
69 for(int i=0,s=1;i<m;i++,s*=B)
70 for(int j=0;j<n;j++)
71 if (!base[j][i]){
72 for(int k=0;k<B;k++)aa[k]=Complex();
73 for(int k=0;k<B;k++)
74 for(int l=0;l<B;l++)aa[k]=aa[k]+a[j+l*s]*invA[l][k];
75 for(int k=0;k<B;k++)a[j+k*s]=aa[k];
76 }
77 }
78 int main(){
79 scanf("%d%d%d",&n,&B,&m);
80 for(int i=0;i<n;i++){
81 x=read();
82 a[x]=a[x]+Complex(1);
83 }
84 n=1;
85 for(int i=0;i<m;i++)n*=B;
86 for(int i=0;i<n;i++){
87 base[i][0]=i%B;
88 for(int j=1;j<m;j++)base[i][j]=base[i/B][j-1];
89 }
90 inv=pow(Complex(B),mod-2);
91 for(int i=0;i<B;i++)
92 for(int j=0;j<B;j++){
93 A[i][j]=Complex(1);
94 AA[i][j]=pow(Complex(0,1),i*j);
95 invA[i][j]=pow(Complex(0,1),B*B-i*j)*inv;
96 }
97 for(int i=0;i<B;i++){
98 memcpy(b[i],a,sizeof(a));
99 DFT(b[i]);
100 for(int j=0;j<B;j++)
101 for(int k=0;k<B;k++)A[j][k]=A[j][k]*AA[j][k];
102 }
103 for(int i=0;i<n;i++)
104 for(int j=0;j<B;j++)
105 for(int k=0;k<B;k++)f[i][j]=f[i][j]+b[k][i]*invA[k][j];
106 for(int i=0;i<n;i++){
107 a[i]=Complex(1);
108 for(int j=0;j<B;j++)a[i]=a[i]*pow(pow(Complex(0,1),j)+Complex(1),f[i][j].get());
109 }
110 IDFT(a);
111 for(int i=0;i<n;i++)printf("%d\n",a[i].get());
112 }

[luogu5577]算力训练的更多相关文章

  1. 百度ERNIE 2.0强势发布!16项中英文任务表现超越BERT和XLNet

    2019年3月,百度正式发布NLP模型ERNIE,其在中文任务中全面超越BERT一度引发业界广泛关注和探讨. 今天,经过短短几个月时间,百度ERNIE再升级.发布持续学习的语义理解框架ERNIE 2. ...

  2. 星际争霸的虫王IA退役2年搞AI,自叹不如了

    ------------恢复内容开始------------ 金磊 发自 凹非寺 量子位|公众号 QbitA 这年头,直播讲AI,真算不上什么新鲜事.但要是连职业电竞选手,都开播主讲呢?没开玩笑,是真 ...

  3. YOLO 从数据集制作到训练

    1.图片数据集收集 共 16种 集装箱船 container ship 散货船 bulker 油船 tanker 游轮 / 客轮 / 邮轮 passenger liner 渔船 fishing boa ...

  4. ubuntu16.04安装tensorflow-gpu和cuda8.0加速训练

    转载请注明出处:http://www.cnblogs.com/buxizhizhoum/p/8086230.html 环境: 系统:ubuntu 16.04 cpu:i5 gpu:gt920m mem ...

  5. 华为云Volcano:让企业AI算力像火山一样爆发

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

  6. 学习AI之NLP后对预训练语言模型——心得体会总结

    一.学习NLP背景介绍:      从2019年4月份开始跟着华为云ModelArts实战营同学们一起进行了6期关于图像深度学习的学习,初步了解了关于图像标注.图像分类.物体检测,图像都目标物体检测等 ...

  7. AI本质就是“暴力计算”?看华为云如何应对算力挑战

    随着AI人工智能技术的飞速发展,相关的AI应用场景已经拓宽至各行各业.你可能想象不到的是,现在大家手上的智能手机的运算能力,甚至比美国航空航天局1969年登月计划中最先进计算机还高出几百上千万倍乃至更 ...

  8. 转pytorch中训练深度神经网络模型的关键知识点

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_42279044/articl ...

  9. 【转载】BERT:用于语义理解的深度双向预训练转换器(Transformer)

    BERT:用于语义理解的深度双向预训练转换器(Transformer)   鉴于最近BERT在人工智能领域特别火,但相关中文资料却很少,因此将BERT论文理论部分(1-3节)翻译成中文以方便大家后续研 ...

随机推荐

  1. css新增属性之边框

    css3新增属性 边框属性 背景属性 文字属性 颜色属性 边框属性 属性 说明 border-radius 设置边框圆角 border-image 设置图像边框 border-shadow 设置边框阴 ...

  2. 题解 2020.10.24 考试 T4 模板

    题目传送门 题目大意 有一个 \(n\) 个点组成的树,有 \(m\) 次操作,每次将 \(1\to x\) 的路径上每个点都加入一个颜色为 \(c\) 的小球.但是每个点都有大小限制,即小球个数超过 ...

  3. JAR文件

    目录 JAR文件 创建JAR文件 jar程序选项 清单文件 注释 可执行JAR文件 警告 多版本JAR文件 注释 关于命令行选项的说明 警告 警告 JAR文件 在将应用程序打包时,你一定希望只向用户提 ...

  4. Upload-labs通关指南(下) 11-20

    承接上篇,这次我们继续做下半部分. 有些题目有其他做法是针对于windows系统特性的,并不能在linux上奏效,因此不在考虑范围之内. Pass-11 制作图片马直接上传 copy a.jpg /a ...

  5. javascriptRemke之类的继承

    前言:es6之前在js中要实现继承,就必须要我们程序员在原型链上手动继承多对象的操作,但是结果往往存在漏洞,为解决这些问题,社区中出现了盗用构造函数.组合继承.原型式继承.寄生式继承等一系列继承方式, ...

  6. JAVA复习总体大纲

    1 java基础. [1].变量--- 数据类型 变量名=值; 数据类型: 1.基本数据类型. byte[1字节] short[2字节] int[4字节] long[8字节] float[4字节] d ...

  7. [技术博客]Unity3d 动画控制

    在制作游戏时,导入的箱子模型本身自带动画.然而,它的动画是一个从打开到关闭的完整过程,并且没有给出控制打开关闭的方法. 最直接的想法是对该动画进行拆分,再封装成不同的动画状态,但是不巧的是,这个动画被 ...

  8. Spring Authorization Server的使用

    Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...

  9. 使用logstash的input file filter收集日志文件

    使用logstash的input file filter收集日志文件 一.需求 二.实现步骤 1.前置知识 2.编写pipeline文件 3.Input 中 file 插件的部分参数解释: 4.启动l ...

  10. Noip模拟11 2021.7.11

    T1 math 其实看看题面,看看给的那机组数据即可看出规律了(然而当时并没有,只是发现模数的循环节,存了个vector,接下来就暴力了) 有个柿子: 其实就是裴蜀定理. 然后想一想的话就是 那么只要 ...