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

    传送门

    前置芝士:微积分(有所了解即可)(可以看看这篇,写得非常详细我看了两章就看不下去了)

    以下都是一些简单的教程切莫当真,仅供理解,建议看更严谨的

    导数:对于一个函数$f(x)$,它的导数$f'(x)$为一个新的函数。简单理解的话,$f'(x)$表示在原函数图像上该点切线的斜率,记为$frac{dy}{dx}$或$frac{d}{dx}f(x)$

    积分:对于一个导数$f'(x)$,它所对应的原函数为它的积分,记为$int f'(x)dx$

    对于一个多项式$F(x)=sum_{i=0}^na_ix^i$来说(一个多项式实际上可以看做一个函数),它的导数和积分如下
    $$F'(x)=sum_{i=1}^nia_ix^{i-1}$$
    $$int F(x)=sum_{i=1}^nfrac{a_ix^{i+1}}{i+1}$$

    这两个是可以$O(n)$计算的,可以互相转换

    然后我们要计算$ln F$,首先因为$ln'(x)=frac{1}{x}$,而这里是一个多项式,根据链式法则(我也不知道什么东西),$frac{dy}{dx}=frac{dy}{du}frac{du}{dx}$,然后把$F(x)$带进去,得$$frac{d}{dx}ln(F(x))=frac{d}{dF(x)}ln(F(x))frac{dF(x)}{dx}$$
    $$frac{d}{dx}ln(F(x))=frac{1}{F}F'$$
    $$ln(F(x))equiv int F'F^{-1}pmod{x^n}$$
    求导和积分的运算代码挺短的……然后剩下的基本就是多项式板子了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define swap(x,y) (x^=y,y^=x,x^=y)
     6 #define mul(x,y) (1ll*x*y%P)
     7 #define add(x,y) (x+y>=P?x+y-P:x+y)
     8 #define dec(x,y) (x-y<0?x-y+P:x-y)
     9 using namespace std;
    10 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    11 char buf[1<<21],*p1=buf,*p2=buf;
    12 inline int read(){
    13     #define num ch-'0'
    14     char ch;bool flag=0;int res;
    15     while(!isdigit(ch=getc()))
    16     (ch=='-')&&(flag=true);
    17     for(res=num;isdigit(ch=getc());res=res*10+num);
    18     (flag)&&(res=-res);
    19     #undef num
    20     return res;
    21 }
    22 char sr[1<<21],z[20];int K=-1,Z;
    23 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
    24 inline void print(int x){
    25     if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x;
    26     while(z[++Z]=x%10+48,x/=10);
    27     while(sr[++K]=z[Z],--Z);sr[++K]=' ';
    28 }
    29 const int N=400005,P=998244353;
    30 inline int ksm(int a,int b){
    31     int res=1;
    32     while(b){
    33         if(b&1) res=mul(res,a);
    34         a=mul(a,a),b>>=1;
    35     }
    36     return res;
    37 }
    38 int n,r[N],A[N],B[N],C[N],D[N],F[N],G[N],O[N];
    39 void NTT(int *A,int type,int len){
    40     int limit=1,l=0;
    41     while(limit<len) limit<<=1,++l;
    42     for(int i=0;i<limit;++i)
    43     r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    44     for(int i=0;i<limit;++i)
    45     if(i<r[i]) swap(A[i],A[r[i]]);
    46     for(int mid=1;mid<limit;mid<<=1){
    47         int R=mid<<1,Wn=ksm(3,(P-1)/R);O[0]=1;
    48         for(int j=1;j<limit;++j) O[j]=mul(O[j-1],Wn);
    49         for(int j=0;j<limit;j+=R){
    50             for(int k=0;k<mid;++k){
    51                 int x=A[j+k],y=mul(O[k],A[j+k+mid]);
    52                 A[j+k]=add(x,y),A[j+k+mid]=dec(x,y);
    53             }
    54         }
    55     }
    56     if(type==-1){
    57         reverse(A+1,A+limit);
    58         for(int i=0,inv=ksm(limit,P-2);i<limit;++i)
    59         A[i]=mul(A[i],inv);
    60     }
    61 }
    62 void Inv(int *a,int *b,int len){
    63     if(len==1) return (void)(b[0]=ksm(a[0],P-2));
    64     Inv(a,b,len>>1);int l=len<<1;
    65     for(int i=0;i<len;++i) C[i]=a[i],D[i]=b[i];
    66     NTT(C,1,l),NTT(D,1,l);
    67     for(int i=0;i<l;++i) C[i]=mul(mul(C[i],D[i]),D[i]);
    68     NTT(C,-1,l);
    69     for(int i=0;i<len;++i) b[i]=dec(add(b[i],b[i]),C[i]);
    70 }
    71 void Direv(int *A,int *B,int len){
    72     //求导
    73     for(int i=1;i<len;++i) B[i-1]=mul(A[i],i);B[len-1]=0; 
    74 }
    75 void Inter(int *A,int *B,int len){
    76     //积分
    77     for(int i=1;i<len;++i) B[i]=mul(A[i-1],ksm(i,P-2)),B[0]=0; 
    78 }
    79 void Ln(int *a,int *b,int len){
    80     Direv(a,A,len),Inv(a,B,len);int l=len<<1;
    81     NTT(A,1,l),NTT(B,1,l);
    82     for(int i=0;i<l;++i) A[i]=mul(A[i],B[i]);
    83     NTT(A,-1,l),Inter(A,b,len);
    84 }
    85 int main(){
    86 //    freopen("testdata.in","r",stdin);
    87     n=read();
    88     for(int i=0;i<n;++i) F[i]=read();
    89     int len;for(len=1;len<n;len<<=1);
    90     Ln(F,G,len);
    91     for(int i=0;i<n;++i) print(G[i]);
    92     Ot();
    93     return 0;
    94 }
  • 相关阅读:
    常见的单链表题目
    一个string类的几个函数
    strcpy和memcpy的区别
    字符串及 strcpy几种写法
    什么函数不能声明为虚函数
    STL中Vector和List的底层数据结构
    C/C++堆、栈及静态数据区详解
    tcp四次握手
    几个知识点
    内存对齐的规则与作用
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9747968.html
Copyright © 2011-2022 走看看