[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节)翻译成中文以方便大家后续研 ...
随机推荐
- VS Code环境配置
1.语言配置 2.Node.js安装配置 系统变量中NODE_PATH,变量值为nodejs的安装路径. 用户变量Path包含%NODE_PATH% 如果说通过CMD打开的命令行可以执行node -v ...
- macbook air m1上传文件到github
一,首先安装git,打开ssh文件里的id_rsa.pub,然后复制所有内容. 二,github上申请自己的账号,右上角settings里选择SSH and GPG keys,点击new ssh ke ...
- 洛谷3613睡觉困难综合征(LCT维护链信息(前后缀)+贪心)
这个题目还是很好啊QWQ很有纪念意义 首先,如果在序列上且是单次询问的话,就是一个非常裸的贪心了QWQ这也是NOI当时原题的问题和数据范围 我们考虑上树的话,应该怎么做? 我的想法是,对于每一位建一个 ...
- 攻防世界XCTF-WEB入门全通关
为了更好的体验,请见我的---->个人博客 XCTF的web块入门区非常简单,适合一些刚接触安全或者对网络安全常识比较了解的同学在安全搞累之余娱乐娱乐. 其主要考察下面几点: 基本的PHP.Py ...
- python 类中的公有属性 私有属性 实例属性
class parent(): i=1 __j=2 class child(parent): m=3 __n=4 def __init__(self,age,name): self.age=age s ...
- javascript-jquery对象的css处理
一.css基本属性处理 1.css()方法:获取css属性值.$("选择器").css(name);//获取匹配选择器的元素指定css属性值. 2.css()方法:设置css属性值 ...
- 保护模式篇——TLB与CPU缓存
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- QG-2019-AAAI-Improving Neural Question Generation using Answer Separation
Improving Neural Question Generation using Answer Separation 本篇是2019年发表在AAAI上的一篇文章.该文章在基础的seq2seq模型的 ...
- ScatterLayout分散布局在kv中的引用
from kivy.uix.scatterlayout import ScatterLayout from kivy.app import App class ScatterLayoutWidget( ...
- Beta_Scrum Meeting_2
会议概要 日期:2021年5月30日 出席人员:除zwh以外的所有人员 会议概述:讨论前两天工作进度以及后两天工作计划 人员分工 组员 负责 前两日完成的工作 后两日即将完成的工作 遇到的困难 hcc ...