zoukankan      html  css  js  c++  java
  • UOJ#34. 多项式乘法

    这是一道模板题。

    给你两个多项式,请输出乘起来后的多项式。

    输入格式

    第一行两个整数 nn 和 mm,分别表示两个多项式的次数。

    第二行 n+1n+1 个整数,分别表示第一个多项式的 00 到 nn 次项前的系数。

    第三行 m+1m+1 个整数,分别表示第一个多项式的 00 到 mm 次项前的系数。

    输出格式

    一行 n+m+1n+m+1 个整数,分别表示乘起来后的多项式的 00 到 n+mn+m 次项前的系数。

    样例一

    input

    1 2
    1 2
    1 2 1
    
    

    output

    1 4 5 2
    
    

    explanation

    (1+2x)(1+2x+x2)=1+4x+5x2+2x3(1+2x)⋅(1+2x+x2)=1+4x+5x2+2x3。

    限制与约定

    0n,m1050≤n,m≤105,保证输入中的系数大于等于 00 且小于等于 99。

    时间限制1s1s

    空间限制256MB

    数学问题 NTT快速数论变换

    模板题

    NTT用数论中的原根代替了FFT中的复数,规避了复数运算的精度误差,但只能在模意义下进行。

    如果模数很大而最终运算结果较小,也可以当做非模意义下的运算来用。(比如说这道题)

    代码和FFT差不多,只是原先是复数运算的地方改掉了。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #define LL long long
     9 using namespace std;
    10 const double pi=acos(-1.0);
    11 const int mod=479*(1<<21)+1;
    12 const int MOD=479*(1<<21)+1;
    13 const int mxn=400010;
    14 int ksm(int a,int k){
    15     int res=1;
    16     while(k){
    17         if(k&1)res=((LL)res*a)%mod;
    18         a=((LL)a*a)%mod;
    19         k>>=1;
    20     }
    21     return res;
    22 }
    23 int n,l;
    24 int a[mxn],b[mxn],rev[mxn];
    25 //
    26 void NTT(int *a,int flag){
    27     int i,j,k;
    28     for(i=0;i<n;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
    29     for(i=1;i<n;i<<=1){
    30         int gn=ksm(3,(mod-1)/(i<<1));
    31         int p=i<<1;
    32         for(j=0;j<n;j+=p){
    33             int g=1;
    34             for(k=0;k<i;k++,g=((LL)g*gn)%mod){
    35                 int x=a[j+k],y=((LL)g*a[i+j+k])%mod;
    36                 a[j+k]=(x+y)%mod;
    37                 a[i+j+k]=(x-y+mod)%mod;
    38             }
    39         }
    40     }
    41     if(flag==-1){
    42         reverse(a+1,a+n);
    43         int inv=ksm(n,mod-2);
    44         for(i=0;i<n;i++)a[i]=((LL)a[i]*inv)%mod;
    45     }
    46     return;
    47 }
    48 char s1[mxn],s2[mxn];
    49 int N,M;
    50 int main(){
    51     int i,j;
    52     scanf("%d%d",&N,&M);
    53     for(i=0;i<=N;i++)scanf("%d",&a[i]);
    54     for(i=0;i<=M;i++)scanf("%d",&b[i]);
    55 //    scanf("%s",s1);
    56 //    scanf("%s",s2);
    57 //    for(i=0;i<N;i++)a[i]=s1[i]-'0';
    58 //    for(i=0;i<M;i++)b[i]=s2[i]-'0';
    59     int m=N+M;
    60     for(n=1;n<=m;n<<=1)l++;
    61     for(i=0;i<n;i++){
    62         rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    63     }
    64     NTT(a,1);NTT(b,1);
    65     for(i=0;i<n;i++)a[i]=((LL)a[i]*b[i]%mod);
    66 //    for(i=0;i<n;i++)printf("%d ",a[i]);
    67 //    printf("
    ");
    68     NTT(a,-1);
    69     for(i=0;i<=m;i++){
    70         printf("%d ",a[i]);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    RIP 动态路由
    9.28 二叉树计数
    9.31 取数理论
    花园
    迟滞变化
    AutoHotkey之自问自答
    几种常见的滤波处理
    快速排序(Quicksort)
    浅谈VBA
    新的开始
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6528875.html
Copyright © 2011-2022 走看看