幂和【膜王降临】

题目大意

给出\(a,b,c,d,P\),求\(\sum_{i\in[a,b]}\sum_{j\in[c,d]}j^i\mod P\)

题解

分析

我们令\(S_{n,k}=\sum_{i\in[0,n]}i^k\)

\[S_{n,k+1}+(n+1)^{k+1} =\sum_{i=0}^n(i+1)^{k+1} =\sum_{i=0}^n\sum_{j=0}^{k+1}C_{k+1}^ji^j\\ =\sum_{i=0}^{k+1}C_{k+1}^i\sum_{j=0}^nj^i=\sum_{i=0}^{k}C_{k+1}^i\sum_{j=0}^nj^i+\sum_{i=0}^{n}i^{k+1} \]

两边同时消掉\(S_{n,k+1}\)

\[(n+1)^{k+1}=\sum_{i=0}^kC_{k+1}^i\sum_{j=0}^nj^i \]

\[(n+1)^{k+1}=\sum_{i=0}^{k-1}C_{k+1}^i\sum_{j=0}^nj^i+(k+1)\sum_{i=0}^ni^k \]

\[(n+1)^{k+1}-\sum_{i=0}^{k-1}C_{k+1}^i\sum_{j=0}^nj^i=(k+1)\sum_{i=0}^ni^k \]

\[\sum_{i=0}^ni^k=\frac{(n+1)^{k+1}-\sum_{i=0}^{k-1}C_{k+1}^i\sum_{j=0}^nj^i}{k+1} \]

\[S_{n,k}=\frac{(n+1)^{k+1}-\sum_{i=0}^{k-1}C_{k+1}^iS_{n,i}}{k+1} \]

我们有了这个递推式即可在\(\Theta(B^2\log_2P)\)的时间内求出我们所需的\(S\)值。

code

#include<bits/stdc++.h>
typedef long long LL;
typedef double db;
using namespace std;
LL P;
LL fpow(LL a,LL b){LL ret=1;
    for(;b;b>>=1,a=a*a%P)
    if(b&1)ret=ret*a%P;
    return ret;
}
const int N=3005;
LL SC[N+5],SD[N+5],C[N+5][N+5];
int main(){LL a,b,c,d;
    scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&P);
    for(int i=0;i<=b+5;i++)
    for(int j=0;j<=i;j++){
        if(!j)C[i][j]=1;
        else C[i][j]=C[i-1][j]+C[i-1][j-1];
        C[i][j]%=P;
    }c=(c+P-1)%P,d=d%P;
    SC[0]=(c+1)%P,SD[0]=(d+1)%P;LL now;
    for(int i=1;i<=b;i++){
        SC[i]=fpow(i+1,P-2),now=fpow(c+1,i+1);
        for(int j=0;j<i;j++)
        now-=C[i+1][j]*SC[j]%P,now=(now+P)%P;
        SC[i]*=now,SC[i]%=P;
    }
    for(int i=1;i<=b;i++){
        SD[i]=fpow(i+1,P-2),now=fpow(d+1,i+1);
        for(int j=0;j<i;j++)
        now-=C[i+1][j]*SD[j]%P,now=(now+P)%P;
        SD[i]*=now,SD[i]%=P;
    }LL ans=0;
    for(int i=a;i<=b;i++)
    ans+=(SD[i]-SC[i]+P)%P,ans%=P;
    printf("%lld",ans);
    return 0;
}
posted @ 2022-08-18 20:30  董哲仁  阅读(48)  评论(0)    收藏  举报