zoukankan      html  css  js  c++  java
  • 洛谷P4725 【模板】多项式对数函数

    https://www.luogu.org/problemnew/show/P4725

    注释:

    $e^x$与$ln(1-x)$的麦克劳林级数:

    $e^x=sum_{i=0}frac{x^i}{i!}$

    $ln(1-x)=-sum_{i=1}frac{x^i}{i}$

    多项式ln,exp就是用这个定义的

    以及,在求ln(y)时的注意点:

    令1-x=y,x=1-y,如果y的常数项不为1,那么x的常数项一定不为0。ln(y)=ln(1-x)=$-sum_{i=1}frac{x^i}{i}$

    x的常数项a对于式子的右侧产生的贡献是$-sum_{i=1}frac{a^i}{i}=ln(1-a)$(或者说ln(y)的常数项是这个),当a不为0时这个东西模意义下一般都没办法算

    做法:看题解 https://www.luogu.org/problemnew/solution/P4725

    设G(x)=ln(F(x))

    两边同时求导,得$G'(x)=ln'(F(x))F'(x)=frac{F'(x)}{F(x)}$

    这样可以求出G'(x),积分后得到G(x)除常数项之外的项

    常数项怎么办?

    根据”注释“的最后一句,G(x)常数项等于模意义下ln(F(x)的常数项),反正F的常数项不为1时,我不会算;刚好题目保证F的常数项为1,那么G(x)常数项就是0

    版本2:基于版本2

      1 #prag
      2 ma GCC optimize(2)
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<cmath>
      8 using namespace std;
      9 #define fi first
     10 #define se second
     11 #define mp make_pair
     12 #define pb push_back
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 const int md=998244353;
     16 const int N=262144;
     17 #define delto(a,b) ((a)-=(b),((a)<0)&&((a)+=md))
     18 int rev[N];
     19 void init(int len)
     20 {
     21     int bit=0,i;
     22     while((1<<(bit+1))<=len)    ++bit;
     23     for(i=0;i<len;++i)
     24         rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
     25 }
     26 ull poww(ull a,ull b)
     27 {
     28     ull base=a,ans=1;
     29     for(;b;b>>=1,base=base*base%md)
     30         if(b&1)
     31             ans=ans*base%md;
     32     return ans;
     33 }
     34 void dft(int *a,int len,int idx)//要求len为2的幂
     35 {
     36     int i,j,k,t1,t2;ull wn,wnk;
     37     for(i=0;i<len;++i)
     38         if(i<rev[i])
     39             swap(a[i],a[rev[i]]);
     40     for(i=1;i<len;i<<=1)
     41     {
     42         wn=poww(idx==1?3:332748118,(md-1)/(i<<1));
     43         for(j=0;j<len;j+=(i<<1))
     44         {
     45             wnk=1;
     46             for(k=j;k<j+i;++k,wnk=wnk*wn%md)
     47             {
     48                 t1=a[k];t2=a[k+i]*wnk%md;
     49                 a[k]+=t2;
     50                 (a[k]>=md) && (a[k]-=md);
     51                 a[k+i]=t1-t2;
     52                 (a[k+i]<0) && (a[k+i]+=md);
     53             }
     54         }
     55     }
     56     if(idx==-1)
     57     {
     58         ull ilen=poww(len,md-2);
     59         for(i=0;i<len;++i)
     60             a[i]=a[i]*ilen%md;
     61     }
     62 }
     63 int t1[N],t2[N],t3[N];
     64 void p_inv(int *f,int *g,int len)//g=f^(-1);f,g数组的长度不小于2^(ceil(log2(len))+1)(需要足够长用于临时存放元素) ;要求len是2的幂
     65 {
     66     g[0]=poww(f[0],md-2);
     67     for(int i=2,j;i<(len<<1);i<<=1)
     68     {
     69         memcpy(t1,f,sizeof(int)*i);
     70         memcpy(t2,g,sizeof(int)*(i>>1));
     71         memset(t2+(i>>1),0,sizeof(int)*(i>>1));
     72         init(i);
     73         dft(t1,i,1);dft(t2,i,1);
     74         for(j=0;j<i;++j)
     75             t1[j]=ull(t1[j])*t2[j]%md;
     76         dft(t1,i,-1);
     77         for(j=0;j<(i>>1);++j)
     78             t1[j]=t1[j+(i>>1)];
     79         memset(t1+(i>>1),0,sizeof(int)*(i>>1));
     80         dft(t1,i,1);
     81         for(j=0;j<i;++j)
     82             t1[j]=ull(t1[j])*t2[j]%md;
     83         dft(t1,i,-1);
     84         for(j=i>>1;j<i;++j)
     85             delto(g[j],t1[j-(i>>1)]);
     86     }
     87 }
     88 int inv[300011];
     89 inline void p_de(int *f,int len)//derivative求导;f=f'
     90 {
     91     for(int i=0;i<len-1;++i)
     92         f[i]=ll(i+1)*f[i+1]%md;
     93     f[len-1]=0;
     94 }
     95 inline void p_in(int *f,int len)//integral积分;f=?f
     96 {
     97     for(int i=len-1;i>=1;--i)
     98         f[i]=ll(f[i-1])*inv[i]%md;
     99     f[0]=0;
    100 }
    101 void p_ln(int *f,int len)//要求len为2的幂
    102 {
    103     p_inv(f,t3,len);p_de(f,len);
    104     init(len<<1);
    105     dft(f,len<<1,1);dft(t3,len<<1,1);
    106     for(int i=0;i<(len<<1);++i)
    107         f[i]=ull(f[i])*t3[i]%md;
    108     dft(f,len<<1,-1);p_in(f,len);
    109 }
    110 int a[N<<1];
    111 int n,n1;
    112 int main()
    113 {
    114     int i,t;
    115     inv[1]=1;
    116     for(i=2;i<=300000;++i)
    117         inv[i]=ull(md-md/i)*inv[md%i]%md;
    118     scanf("%d",&n);n1=n;
    119     for(i=0;i<n;++i)
    120         scanf("%d",a+i);
    121     for(t=1;t<n;t<<=1);
    122     n=t;
    123     p_ln(a,n);
    124     for(i=0;i<n1;++i)
    125         printf("%d ",a[i]);
    126     return 0;
    127 }
    View Code

    版本3:基于版本3

      1 #prag
      2 ma GCC optimize(2)
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<cmath>
      8 using namespace std;
      9 #define fi first
     10 #define se second
     11 #define mp make_pair
     12 #define pb push_back
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 const int md=998244353;
     16 const int N=262144;
     17 #define delto(a,b) ((a)-=(b),((a)<0)&&((a)+=md))
     18 int rev[N];
     19 void init(int len)
     20 {
     21     int bit=0,i;
     22     while((1<<(bit+1))<=len)    ++bit;
     23     for(i=0;i<len;++i)
     24         rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
     25 }
     26 ull poww(ull a,ull b)
     27 {
     28     ull base=a,ans=1;
     29     for(;b;b>>=1,base=base*base%md)
     30         if(b&1)
     31             ans=ans*base%md;
     32     return ans;
     33 }
     34 void dft(int *a,int len,int idx)//要求len为2的幂
     35 {
     36     int i,j,k,t1,t2;ull wn,wnk;
     37     for(i=0;i<len;++i)
     38         if(i<rev[i])
     39             swap(a[i],a[rev[i]]);
     40     for(i=1;i<len;i<<=1)
     41     {
     42         wn=poww(idx==1?3:332748118,(md-1)/(i<<1));
     43         for(j=0;j<len;j+=(i<<1))
     44         {
     45             wnk=1;
     46             for(k=j;k<j+i;++k,wnk=wnk*wn%md)
     47             {
     48                 t1=a[k];t2=a[k+i]*wnk%md;
     49                 a[k]+=t2;
     50                 (a[k]>=md) && (a[k]-=md);
     51                 a[k+i]=t1-t2;
     52                 (a[k+i]<0) && (a[k+i]+=md);
     53             }
     54         }
     55     }
     56     if(idx==-1)
     57     {
     58         ull ilen=poww(len,md-2);
     59         for(i=0;i<len;++i)
     60             a[i]=a[i]*ilen%md;
     61     }
     62 }
     63 void p_inv(int *f,int *g,int len)//g=f^(-1);f,g数组的长度不小于2len(需要足够长用于临时存放元素) ;要求len是2的幂
     64 {
     65     static int t1[N],t2[N];
     66     g[0]=poww(f[0],md-2);
     67     for(int i=2,j;i<(len<<1);i<<=1)
     68     {
     69         memcpy(t1,f,sizeof(int)*i);
     70         memcpy(t2,g,sizeof(int)*(i>>1));
     71         memset(t2+(i>>1),0,sizeof(int)*(i>>1));
     72         init(i);
     73         dft(t1,i,1);dft(t2,i,1);
     74         for(j=0;j<i;++j)
     75             t1[j]=ull(t1[j])*t2[j]%md;
     76         dft(t1,i,-1);
     77         for(j=0;j<(i>>1);++j)
     78             t1[j]=t1[j+(i>>1)];
     79         memset(t1+(i>>1),0,sizeof(int)*(i>>1));
     80         dft(t1,i,1);
     81         for(j=0;j<i;++j)
     82             t1[j]=ull(t1[j])*t2[j]%md;
     83         dft(t1,i,-1);
     84         for(j=i>>1;j<i;++j)
     85             g[j]=md-t1[j-(i>>1)];
     86     }
     87 }
     88 int inv[300011];
     89 inline void p_de(int *f,int len)//derivative求导;f=f'
     90 {
     91     for(int i=0;i<len-1;++i)
     92         f[i]=ll(i+1)*f[i+1]%md;
     93     f[len-1]=0;
     94 }
     95 inline void p_in(int *f,int len)//integral积分;f=?f
     96 {
     97     for(int i=len-1;i>=1;--i)
     98         f[i]=ll(f[i-1])*inv[i]%md;
     99     f[0]=0;
    100 }
    101 void p_ln(int *f,int len)//要求len为2的幂
    102 {
    103     static int t3[N];
    104     p_inv(f,t3,len);p_de(f,len);
    105     init(len<<1);
    106     dft(f,len<<1,1);dft(t3,len<<1,1);
    107     for(int i=0;i<(len<<1);++i)
    108         f[i]=ull(f[i])*t3[i]%md;
    109     dft(f,len<<1,-1);p_in(f,len);
    110 }
    111 int a[N<<1];
    112 int n,n1;
    113 int main()
    114 {
    115     int i,t;
    116     inv[1]=1;
    117     for(i=2;i<=300000;++i)
    118         inv[i]=ull(md-md/i)*inv[md%i]%md;
    119     scanf("%d",&n);n1=n;
    120     for(i=0;i<n;++i)
    121         scanf("%d",a+i);
    122     for(t=1;t<n;t<<=1);
    123     n=t;
    124     p_ln(a,n);
    125     for(i=0;i<n1;++i)
    126         printf("%d ",a[i]);
    127     return 0;
    128 }
    View Code
  • 相关阅读:
    简单bb两句
    P2894 [USACO08FEB]Hotel G
    文艺平衡树
    CS184.1X 计算机图形学导论作业1
    C++ Primer Plus章节编程练习(第五章)
    C++ Primer Plus章节编程练习(第六章)
    CS184.1X 计算机图形学导论作业0
    C++ Primer Plus章节编程练习(第四章)
    计算机图形学之光栅图形学算法
    Codeforces 980B
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10555607.html
Copyright © 2011-2022 走看看