• 【xsy2978】Product of Roots 生成函数+多项式ln+多项式exp


    题目大意:给你两个多项式$f(x)$和$g(x)$,满足$f(x)=\prod\limits_{i=1}^{n}(a_i+1)$,$g(x)=\prod\limits_{i=1}^{m}(b_i+1)$。

    现在给你一个多项式$h(x)$,满足$h(x)=\prod\limits_{i=1}^{n}\prod\limits_{j=1}^{m}(a_ib_j+1)$

    请输出多项式$h$的前$k$项,在模$998244353$意义下进行。

    数据范围:$n,m≤10^5$。

    我们现在有:

    $f(x)=\prod\limits_{i=1}^{n}(a_i+1)$

    我们在等式两边都取对数,然后泰勒展开,得到:

    $\begin{align} ln \big(f(x)\big) =&\sum\limits_{i=1}^{n} ln(a_i+1) \\=&\sum\limits_{i=1}^{n} \sum_{k=1}^{\infty} \frac{(-1)^{k+1}}{k}x^ka_i^{k}\end{align}$

    我们不难推出:

    $[x^k]ln(f(x))=\sum\limits_{i=1}^{n} \frac{(-1)^{k+1}}{k}a_i^{k}$

    $g(x)$同理。

     

    我们现在来考虑$h(x)$,我们现在有:

    $h(x)=\prod\limits_{i=1}^{n}\prod\limits_{j=1}^{m}(a_ib_j+1)$

    和上面一样,我们在等式两边都取对数,然后泰勒展开,得到:

    $\begin{align}
    ln\big(h(x)\big) =&\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ln(a_ib_j+1)\\
    =&\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum_{k=1}^{\infty} \frac{(-1)^{k+1}}{k}x^ka_i^{k}b_j^{k}\\
    =&\sum\limits_{k=1}^{\infty}x^k \sum\limits_{i=1}^{n} \frac{(-1)^{k+1}}{k}a_i^{k}\sum\limits_{i=1}^{m} b_i^{k}\\
    =&\sum\limits_{k=1}^{\infty}\frac{k}{(-1)^{k+1}}x^k \sum\limits_{i=1}^{n} \frac{(-1)^{k+1}}{k}a_i^{k}\sum\limits_{i=1}^{m} \frac{(-1)^{k+1}}{k}b_i^{k}\\
    \end{align}$

    我们不难推出:

    $\begin{align}[x^k]ln(h(x))=&\frac{k}{(-1)^{k+1}} \sum\limits_{i=1}^{n} \frac{(-1)^{k+1}}{k}a_i^{k}\sum\limits_{i=1}^{m} \frac{(-1)^{k+1}}{k}b_i^{k}\\
    =&\frac{k}{(-1)^{k+1}}[x^k]ln\big(f(x)\big)[x^k]ln\big(g(x)\big)
    \end{align}$

    我们可以考虑,用多项式求$ln$,求出$ln\big(f(x)\big)$和$ln\big(g(x)\big)$,然后求出$ln(h(x))$后再用多项式$exp$算回去,就得到多项式$h$了。

    套一个多项式的板子就可以了。

    完结撒花

      1 #include<bits/stdc++.h>
      2 #define M (1<<19)
      3 #define L long long
      4 #define MOD 998244353
      5 #define G 3
      6 using namespace std;
      7 
      8 L pow_mod(L x,L k){
      9     L ans=1;
     10     while(k){
     11         if(k&1) ans=ans*x%MOD;
     12         x=x*x%MOD; k>>=1;
     13     }
     14     return ans;
     15 }
     16 
     17 void change(L a[],int n){
     18     for(int i=0,j=0;i<n-1;i++){
     19         if(i<j) swap(a[i],a[j]);
     20         int k=n>>1;
     21         while(j>=k) j-=k,k>>=1;
     22         j+=k;
     23     }
     24 }
     25 void NTT(L a[],int n,int on){
     26     change(a,n);
     27     for(int h=2;h<=n;h<<=1){
     28         L wn=pow_mod(G,(MOD-1)/h);
     29         for(int j=0;j<n;j+=h){
     30             L w=1;
     31             for(int k=j;k<j+(h>>1);k++){
     32                 L u=a[k],t=w*a[k+(h>>1)]%MOD;
     33                 a[k]=(u+t)%MOD;
     34                 a[k+(h>>1)]=(u-t+MOD)%MOD;
     35                 w=w*wn%MOD;
     36             }
     37         }
     38     }
     39     if(on==-1){
     40         L inv=pow_mod(n,MOD-2);
     41         for(int i=0;i<n;i++) a[i]=a[i]*inv%MOD;
     42         reverse(a+1,a+n);
     43     }
     44 }
     45 
     46 void getinv(L a[],L b[],int n){
     47     if(n==1){b[0]=pow_mod(a[0],MOD-2); return;}
     48     static L c[M],d[M];
     49     memset(c,0,n<<4); memset(d,0,n<<4);
     50     getinv(a,c,n>>1);
     51     for(int i=0;i<n;i++) d[i]=a[i];
     52     NTT(d,n<<1,1); NTT(c,n<<1,1);
     53     for(int i=0;i<(n<<1);i++) b[i]=(2*c[i]-d[i]*c[i]%MOD*c[i]%MOD+MOD)%MOD;
     54     NTT(b,n<<1,-1);
     55     for(int i=0;i<n;i++) b[n+i]=0;
     56 }
     57 
     58 void qiudao(L a[],L b[],int n){
     59     memset(b,0,sizeof(b));
     60     for(int i=1;i<n;i++) b[i-1]=i*a[i]%MOD;
     61 }
     62 void jifen(L a[],L b[],int n){
     63     memset(b,0,sizeof(b));
     64     for(int i=0;i<n;i++) b[i+1]=a[i]*pow_mod(i+1,MOD-2)%MOD;
     65 }
     66 
     67 void getln(L a[],L b[],int n){
     68     static L c[M],d[M];
     69     memset(c,0,n<<4); memset(d,0,n<<4);
     70     qiudao(a,c,n); getinv(a,d,n);
     71     NTT(c,n<<1,1); NTT(d,n<<1,1);
     72     for(int i=0;i<(n<<1);i++) c[i]=c[i]*d[i]%MOD;
     73     NTT(c,n<<1,-1);
     74     jifen(c,b,n);
     75 }
     76 
     77 void getexp(L a[],L b[],int n){
     78     if(n==1){b[0]=1; return;}
     79     static L lnb[M]; memset(lnb,0,n<<4);
     80     getexp(a,b,n>>1); getln(b,lnb,n);
     81     for(int i=0;i<n;i++) lnb[i]=(a[i]-lnb[i]+MOD)%MOD,b[i+n]=0;
     82     lnb[n]=0;
     83     lnb[0]=(lnb[0]+1)%MOD;
     84     NTT(lnb,n<<1,1); NTT(b,n<<1,1);
     85     for(int i=0;i<(n<<1);i++) b[i]=b[i]*lnb[i]%MOD;
     86     NTT(b,n<<1,-1);
     87     for(int i=0;i<n;i++) b[i+n]=0;
     88 }
     89 
     90 int n,m,k,len;
     91 L f[M]={0},g[M]={0},h[M]={0},lf[M]={0},lg[M]={0},lh[M]={0};
     92 
     93 int main(){
     94     scanf("%d%d%d",&n,&m,&k);
     95     for(len=1;len<=(n+m+2);len<<=1);
     96     for(int i=0;i<=n;i++) scanf("%lld",f+i);
     97     for(int i=0;i<=m;i++) scanf("%lld",g+i);
     98     getln(f,lf,len);
     99     getln(g,lg,len);
    100     for(int i=0;i<len;i++) lh[i]=(lf[i]*lg[i]%MOD*(i&1?i:-i)%MOD+MOD)%MOD;
    101     getexp(lh,h,len);
    102     for(int i=0;i<k;i++) printf("%lld ",h[i]);
    103 }
  • 相关阅读:
    bat入门--第一个bat文件
    Egret的Shape
    Less Time, More profit 最大权闭合子图(最大流最小割)
    Mayor's posters POJ
    Stars POJ
    Snacks
    有趣的数列 卡特兰数
    Devu and Flowers lucas定理+容斥原理
    整数分解为2的幂 数学
    易碎的鸟蛋 概率DP
  • 原文地址:https://www.cnblogs.com/alphainf/p/10836517.html
Copyright © 2020-2023  润新知