今天的A题。裸的ntt,但我不会,于是白送了50分。

于是跑来学一下ntt。

题面非常easy。就懒得贴了,那不是我要说的重点。

重点是NTT,也称高速数论变换。

在非常多问题中,我们可能会遇到在模意义下的多项式乘法问题,这时传统的高速傅里叶变换可能就无法满足要求,这时候高速数论变换就派上了用场。

考虑高速傅里叶变换的实现,利用单位复根的特殊性质来降低运算。而利用的。就是dft变换的循环卷积特性。

于是考虑在模意义下相同具有循环卷积特性的东西。

考虑在模p意义下(p为特定的质数,满足p=c∗2n+1)

我们令p的一个原根为g,于是类比fft,我们的单位根为gp−1n,然后其他的处理都类比fft。

UPD:这是uoj34的代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef double db;
  5. const int inf=0x3f3f3f3f;
  6. int getint()
  7. {
  8. int f=1,g=0;char c=getchar();
  9. while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
  10. while(c>='0' && c<='9')g=(g<<3)+(g<<1)+c-'0',c=getchar();
  11. return f*g;
  12. }
  13. const int maxn=300005;
  14. const int mod=998244353;
  15. const int G=3;
  16. int a[maxn];
  17. int b[maxn];
  18. int c[maxn];
  19. int n,m;
  20. int rev[maxn];
  21. int N;
  22. int len;
  23. int inv;
  24. int power(ll x,ll y)
  25. {
  26. ll res=1ll;
  27. for(;y;y>>=1,x=(x*x)%mod)
  28. {
  29. if(y&1)res=(res*x)%mod;
  30. }
  31. return res;
  32. }
  33. void init()
  34. {
  35. while((n+m)>=(1<<len))len++;
  36. N=(1<<len);
  37. inv=power(N,mod-2);
  38. for(int i=0;i<N;i++)
  39. {
  40. int pos=0;
  41. int temp=i;
  42. for(int j=1;j<=len;j++)
  43. {
  44. pos<<=1;pos |= temp&1;temp>>=1;
  45. }
  46. rev[i]=pos;
  47. }
  48. }
  49. void ntt(int *a,int n,int re)
  50. {
  51. for(int i=0;i<n;i++)
  52. {
  53. if(rev[i]>i)
  54. {
  55. swap(a[i],a[rev[i]]);
  56. }
  57. }
  58. for(int i=2;i<=n;i<<=1)
  59. {
  60. int mid=i>>1;
  61. int wn=power(G,(mod-1)/i);
  62. if(re) wn=power(wn,(mod-2));
  63. for(int j=0;j<n;j+=i)
  64. {
  65. int w=1;
  66. for(int k=0;k<mid;k++)
  67. {
  68. int temp1=a[j+k];
  69. int temp2=(ll)a[j+k+mid]*w%mod;
  70. a[j+k]=(temp1+temp2);if(a[j+k]>=mod)a[j+k]-=mod;
  71. a[j+k+mid]=(temp1-temp2);if(a[j+k+mid]<0)a[j+k+mid]+=mod;
  72. w=(ll)w*wn%mod;
  73. }
  74. }
  75. }
  76. if(re)
  77. {
  78. for(int i=0;i<n;i++)
  79. {
  80. a[i]=(ll)a[i]*inv%mod;
  81. }
  82. }
  83. }
  84. int main()
  85. {
  86. n=getint();
  87. m=getint();
  88. for(int i=0;i<=n;i++)
  89. {
  90. a[i]=getint();
  91. }
  92. for(int i=0;i<=m;i++)
  93. {
  94. b[i]=getint();
  95. }
  96. init();
  97. ntt(a,N,0);
  98. ntt(b,N,0);
  99. for(int i=0;i<=N;i++)
  100. {
  101. c[i]=(ll)a[i]*b[i]%mod;
  102. }
  103. ntt(c,N,1);
  104. for(int i=0;i<=n+m;i++)
  105. {
  106. printf("%d%c",c[i]," \n"[i==n+m]);
  107. }
  108. return 0;
  109. }

高速数论变换(NTT)的更多相关文章

  1. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  2. 从傅里叶变换(FFT)到数论变换(NTT)

    FFT可以用来计算多项式乘法,但是复数的运算中含有大量的浮点数,精度较低.对于只有整数参与运算的多项式,有时,\(\text{NTT(Number-Theoretic Transform)}\)会是更 ...

  3. 【算法】快速数论变换(NTT)初探

    [简介] 快速傅里叶变换(FFT)运用了单位复根的性质减少了运算,但是每个复数系数的实部和虚部是一个余弦和正弦函数,因此系数都是浮点数,而浮点数的运算速度较慢且可能产生误差等精度问题,因此提出了以数论 ...

  4. Algorithm: 多项式乘法 Polynomial Multiplication: 快速傅里叶变换 FFT / 快速数论变换 NTT

    Intro: 本篇博客将会从朴素乘法讲起,经过分治乘法,到达FFT和NTT 旨在能够让读者(也让自己)充分理解其思想 模板题入口:洛谷 P3803 [模板]多项式乘法(FFT) 朴素乘法 约定:两个多 ...

  5. 快速傅里叶变换FFT& 数论变换NTT

    相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...

  6. [快速数论变换 NTT]

    先粘一个模板.这是求高精度乘法的 #include <bits/stdc++.h> #define maxn 1010 using namespace std; char s[maxn]; ...

  7. 快速数论变换(NTT)小结

    NTT 在FFT中,我们需要用到复数,复数虽然很神奇,但是它也有自己的局限性--需要用double类型计算,精度太低 那有没有什么东西能够代替复数且解决精度问题呢? 这个东西,叫原根 原根 阶 若\( ...

  8. JZYZOJ 2041 快速数论变换 NTT 多项式

    http://172.20.6.3/Problem_Show.asp?id=2041 https://blog.csdn.net/ggn_2015/article/details/68922404 代 ...

  9. 模板 - 数学 - 多项式 - 快速数论变换/NTT

    Huffman分治的NTT,常数一般.使用的时候把多项式的系数们放进vector里面,然后调用solve就可以得到它们的乘积.注意这里默认最大长度是1e6,可能需要改变. #include<bi ...

随机推荐

  1. python之禅---对象与元类

    众所周知,python是一门面向对象的编程语言,python中一切皆对象,那么我们先探讨一下什么是对象. 一.对象 在生活中一个事物就是一个对象,比如:一只猫就是一个对象,猫的体型.猫毛的颜色等是它的 ...

  2. 题解 CF327C 【Magic Five】

    这道题带坑,假如没有发现肯定会爆. 首先先搜索一遍0和5,储存在数组a里面. 那么应当有2 ^ a1 +2 ^ a2 +...+ 2 ^ an. 然而这道题没那么简单,数串还可以重复k次. 因此,需要 ...

  3. 【UVa 1347】Tour

    [Link]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  4. 公路通行税Ceoi99(BFS+图的直径)

    公路通行税(Ceoi99) 版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址! 在PALMIA国家内,有N个城市由公路相连(每条 ...

  5. NYOJ_77 开灯问题

    题目地址 分析: 用一个数组来保存每盏灯的操作的次数.推断奇偶就可以推断灯的状态. 最后的输出格式须要注意一下空格的位置,思路就是现输出一个.剩下来的输出在前面加一个空格. 空格用_表示: 1_3_5 ...

  6. mysql查询今天,昨天,近7天,近30天,本月,上一月数据

    近期项目中用到了查询当月数据记录的功能,最初的想法是在逻辑业务里构造好时间段进行查询,当写sql语句时感觉挺麻烦.所以就到网上搜索了一下,看看是不是能有简单的方法.果然.网络资源非常强大.以下结合我的 ...

  7. 学习 shell —— 创建序列数组

    list/array 1. seq 方法创建 基本用法: $ a_num_seq = ($seq 5) $ echo $a_num_seq 1 2 3 4 5 a_num_seq 得到是字符串,不同之 ...

  8. docker 笔记1

    如果想要删除所有container的话再加一个指令: docker stop $(docker ps -a -q) 如果想要删除所有container的话再加一个指令: docker rm $(doc ...

  9. Android 勤用RXJava compose操作符消除重复代码

    相信小伙伴在使用RXJava与Retrofit请求网络时,都有遇到过这样的场景,在IO线程请求网络解析数据,接着返回主线程setData.更新View试图,那么也肯定熟悉下面这几句代码: .subsc ...

  10. url传递中文的解决方案总结

    File文件控件,选中文件(图片,flash,视频)即立即预览显示 .Net刷新页面的几种方式 Attributes.Add用途与用法(C#) url传递中文的解决方案总结 byte[] bytes ...