[luogu5577]算力训练
(以下以$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]算力训练的更多相关文章
- 百度ERNIE 2.0强势发布!16项中英文任务表现超越BERT和XLNet
2019年3月,百度正式发布NLP模型ERNIE,其在中文任务中全面超越BERT一度引发业界广泛关注和探讨. 今天,经过短短几个月时间,百度ERNIE再升级.发布持续学习的语义理解框架ERNIE 2. ...
- 星际争霸的虫王IA退役2年搞AI,自叹不如了
------------恢复内容开始------------ 金磊 发自 凹非寺 量子位|公众号 QbitA 这年头,直播讲AI,真算不上什么新鲜事.但要是连职业电竞选手,都开播主讲呢?没开玩笑,是真 ...
- YOLO 从数据集制作到训练
1.图片数据集收集 共 16种 集装箱船 container ship 散货船 bulker 油船 tanker 游轮 / 客轮 / 邮轮 passenger liner 渔船 fishing boa ...
- ubuntu16.04安装tensorflow-gpu和cuda8.0加速训练
转载请注明出处:http://www.cnblogs.com/buxizhizhoum/p/8086230.html 环境: 系统:ubuntu 16.04 cpu:i5 gpu:gt920m mem ...
- 华为云Volcano:让企业AI算力像火山一样爆发
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- 学习AI之NLP后对预训练语言模型——心得体会总结
一.学习NLP背景介绍: 从2019年4月份开始跟着华为云ModelArts实战营同学们一起进行了6期关于图像深度学习的学习,初步了解了关于图像标注.图像分类.物体检测,图像都目标物体检测等 ...
- AI本质就是“暴力计算”?看华为云如何应对算力挑战
随着AI人工智能技术的飞速发展,相关的AI应用场景已经拓宽至各行各业.你可能想象不到的是,现在大家手上的智能手机的运算能力,甚至比美国航空航天局1969年登月计划中最先进计算机还高出几百上千万倍乃至更 ...
- 转pytorch中训练深度神经网络模型的关键知识点
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_42279044/articl ...
- 【转载】BERT:用于语义理解的深度双向预训练转换器(Transformer)
BERT:用于语义理解的深度双向预训练转换器(Transformer) 鉴于最近BERT在人工智能领域特别火,但相关中文资料却很少,因此将BERT论文理论部分(1-3节)翻译成中文以方便大家后续研 ...
随机推荐
- css新增属性之边框
css3新增属性 边框属性 背景属性 文字属性 颜色属性 边框属性 属性 说明 border-radius 设置边框圆角 border-image 设置图像边框 border-shadow 设置边框阴 ...
- 题解 2020.10.24 考试 T4 模板
题目传送门 题目大意 有一个 \(n\) 个点组成的树,有 \(m\) 次操作,每次将 \(1\to x\) 的路径上每个点都加入一个颜色为 \(c\) 的小球.但是每个点都有大小限制,即小球个数超过 ...
- JAR文件
目录 JAR文件 创建JAR文件 jar程序选项 清单文件 注释 可执行JAR文件 警告 多版本JAR文件 注释 关于命令行选项的说明 警告 警告 JAR文件 在将应用程序打包时,你一定希望只向用户提 ...
- Upload-labs通关指南(下) 11-20
承接上篇,这次我们继续做下半部分. 有些题目有其他做法是针对于windows系统特性的,并不能在linux上奏效,因此不在考虑范围之内. Pass-11 制作图片马直接上传 copy a.jpg /a ...
- javascriptRemke之类的继承
前言:es6之前在js中要实现继承,就必须要我们程序员在原型链上手动继承多对象的操作,但是结果往往存在漏洞,为解决这些问题,社区中出现了盗用构造函数.组合继承.原型式继承.寄生式继承等一系列继承方式, ...
- JAVA复习总体大纲
1 java基础. [1].变量--- 数据类型 变量名=值; 数据类型: 1.基本数据类型. byte[1字节] short[2字节] int[4字节] long[8字节] float[4字节] d ...
- [技术博客]Unity3d 动画控制
在制作游戏时,导入的箱子模型本身自带动画.然而,它的动画是一个从打开到关闭的完整过程,并且没有给出控制打开关闭的方法. 最直接的想法是对该动画进行拆分,再封装成不同的动画状态,但是不巧的是,这个动画被 ...
- Spring Authorization Server的使用
Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...
- 使用logstash的input file filter收集日志文件
使用logstash的input file filter收集日志文件 一.需求 二.实现步骤 1.前置知识 2.编写pipeline文件 3.Input 中 file 插件的部分参数解释: 4.启动l ...
- Noip模拟11 2021.7.11
T1 math 其实看看题面,看看给的那机组数据即可看出规律了(然而当时并没有,只是发现模数的循环节,存了个vector,接下来就暴力了) 有个柿子: 其实就是裴蜀定理. 然后想一想的话就是 那么只要 ...