• 洛谷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
  • 相关阅读:
    重新想象 Windows 8 Store Apps (15) 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager
    重新想象 Windows 8 Store Apps (12) 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
    返璞归真 asp.net mvc (10) asp.net mvc 4.0 新特性之 Web API
    与众不同 windows phone (29) Communication(通信)之与 OData 服务通信
    与众不同 windows phone (33) Communication(通信)之源特定组播 SSM(Source Specific Multicast)
    与众不同 windows phone (27) Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
    与众不同 windows phone (30) Communication(通信)之基于 Socket TCP 开发一个多人聊天室
    返璞归真 asp.net mvc (12) asp.net mvc 4.0 新特性之移动特性
    重新想象 Windows 8 Store Apps (2) 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, RadioButton, CheckBox, ToggleSwitch
    重新想象 Windows 8 Store Apps (10) 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10555607.html
Copyright © 2020-2023  润新知