一阶微分方程

· · 算法·理论

常数变易法

考虑以下一阶线性微分方程

\dfrac{\text{d}y}{\text{d}x}=P(x)y+Q(x)

先解齐次方程

\begin{aligned} \dfrac{\text{d}y}{\text{d}x}&=P(x)y\\ \dfrac{\text{d}y}{y}&=P(x)\text{d}x\\ \ln y&=P_1(x)+C\\ y&=C\exp(P_1(x)) \end{aligned}

其中

P_1(x)=\int P(x)\text{d}x

根据常数变易法,对于原非齐次方程有

y=C(x)\exp(P_1(x))

即将 C 改为关于 x 的函数 C(x)

y 代回原方程即可解出 C(x)

这个方法可以拓展到非线性微分方程。

P6613

考虑以下方程

\frac{\text dF(x)}{\text dx} \equiv A(x)\text e^{F(x)-1}+B(x) \pmod{x^n}

y=F(x),先解齐次方程

\begin{aligned} \dfrac{\text dy}{\text dx}&=A(x)\exp(y-1)\\ \dfrac{\text{d}y}{\exp(y-1)}&=A(x)\text{d}x\\ \exp(1-y)\text{d}y&=A(x)\text{d}x\\ -\exp(1-y)&=A_1(x)-C\\ \exp(1-y)&=C-A_1(x)\\ 1-y&=\ln(C-A_1(x))\\ y&=1-\ln(C-A_1(x))\\ y&=1+\ln\dfrac{1}{C-A_1(x)} \end{aligned}

其中

A_1(x)=\int A(x)\text{d}x

根据常数变易法,对于原非齐次方程有

\begin{aligned} y&=1-\ln(C(x)-A_1(x))\\ y&=1+\ln\dfrac{1}{C(x)-A_1(x)} \end{aligned}

代回原方程

\begin{aligned} \dfrac{\text dy}{\text dx}&=A(x)\exp(y-1)+B(x)\\ -\dfrac{C'(x)-A(x)}{C(x)-A_1(x)}&=\dfrac{A(x)}{C(x)-A_1(x)}+B(x)\\ \dfrac{C'(x)}{C(x)-A_1(x)}&=-B(x)\\ C'(x)&=-B(x)C(x)+A_1(x)B(x) \end{aligned}

z=C(x)

z'=-B(x)z+A_1(x)B(x)

解此方程,求出通解

z=C_1(x)\exp(-B_1(x))

其中

B_1(x)=\int B(x)\text{d}x

代入得

\begin{aligned} z'&=-B(x)z+A_1(x)B(x)\\ C_1'(x)\exp(-B_1(x))-C_1(x)\exp(-B_1(x))B(x)&=-B(x)C_1(x)\exp(-B_1(x))+A_1(x)B(x)\\ C_1'(x)\exp(-B_1(x))&=A_1(x)B(x)\\ C_1(x)&=\int A_1(x)B(x)\exp(B_1(x))\text{d}x+C \end{aligned}

继续回代

C(x)=\left(\int A_1(x)B(x)\exp(B_1(x))\text{d}x+C\right)\exp(-B_1(x)) \begin{aligned} F(x)&=1-\ln\left(\left(\int A_1(x)B(x)\exp(B_1(x))\text{d}x+C\right)\exp(-B_1(x))-A_1(x)\right)\\ &=1+B_1(x)-\ln\left(\int A_1(x)B(x)\exp(B_1(x))\text{d}x-A_1(x)\exp(B_1(x))+C\right) \end{aligned}

x=0F(x)=1,故取 C=1

注意到

B(x)\exp(B_1(x))=\exp(B_1(x))'

以及

A_1(x)\exp(B_1(x))'=(A_1(x)\exp(B_1(x)))'-A(x)\exp(B_1(x))

所以

F(x)=1+B_1(x)-\ln(1-\int {A(x)\exp(B_1(x))\text{d}x})

直接计算即可。

Code

int main(){
    int n;
    scanf("%d",&n);
    n++;
    for(int i=0;i<=n-1;i++){
        scanf("%llu",&a[i]);
    }
    for(int i=0;i<=n-1;i++){
        scanf("%llu",&b[i]);
        b1[i]=b[i];
    }
    inv[1]=1;
    for(int i=2;i<=n;i++){
        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    }
    ITG(b1,n);
    EXP(b1,c,n);
    CPY(ans,b1,n);
    ans[0]=(ans[0]+1)%mod;
    CLR(b1,n);
    MUL(a,c,n<<1);
    CLR(a+n,n);
    ITG(a,n);
    a[0]=(1-a[0]+mod)%mod;
    for(int i=1;i<=n-1;i++){
        a[i]=(mod-a[i])%mod;
    }
    LN(a,c,n);
    DEC(ans,c,n);
    for(int i=0;i<=n-1;i++){
        printf("%llu ",ans[i]);
    }
}