幂和【膜王降临模拟赛】

题目大意

给出 a , b , c , d , P a,b,c,d,P a,b,c,d,P,求 ∑ i ∈ [ a , b ] ∑ j ∈ [ c , d ] j i m o d    P \sum_{i\in[a,b]}\sum_{j\in[c,d]}j^i\mod P i[a,b]j[c,d]jimodP

题解

分析

我们令 S n , k = ∑ i ∈ [ 0 , n ] i k S_{n,k}=\sum_{i\in[0,n]}i^k Sn,k=i[0,n]ik


S n , k + 1 + ( n + 1 ) k + 1 = ∑ i = 0 n ( i + 1 ) k + 1 = ∑ i = 0 n ∑ j = 0 k + 1 C k + 1 j i j = ∑ i = 0 k + 1 C k + 1 i ∑ j = 0 n j i = ∑ i = 0 k C k + 1 i ∑ j = 0 n j i + ∑ i = 0 n i k + 1 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} Sn,k+1+(n+1)k+1=i=0n(i+1)k+1=i=0nj=0k+1Ck+1jij=i=0k+1Ck+1ij=0nji=i=0kCk+1ij=0nji+i=0nik+1
两边同时消掉 S n , k + 1 S_{n,k+1} Sn,k+1


( n + 1 ) k + 1 = ∑ i = 0 k C k + 1 i ∑ j = 0 n j i (n+1)^{k+1}=\sum_{i=0}^kC_{k+1}^i\sum_{j=0}^nj^i (n+1)k+1=i=0kCk+1ij=0nji

( n + 1 ) k + 1 = ∑ i = 0 k − 1 C k + 1 i ∑ j = 0 n j i + ( k + 1 ) ∑ i = 0 n i 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 (n+1)k+1=i=0k1Ck+1ij=0nji+(k+1)i=0nik

( n + 1 ) k + 1 − ∑ i = 0 k − 1 C k + 1 i ∑ j = 0 n j i = ( k + 1 ) ∑ i = 0 n i 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 (n+1)k+1i=0k1Ck+1ij=0nji=(k+1)i=0nik

∑ i = 0 n i k = ( n + 1 ) k + 1 − ∑ i = 0 k − 1 C k + 1 i ∑ j = 0 n j i k + 1 \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} i=0nik=k+1(n+1)k+1i=0k1Ck+1ij=0nji


S n , k = ( n + 1 ) k + 1 − ∑ i = 0 k − 1 C k + 1 i S n , i k + 1 S_{n,k}=\frac{(n+1)^{k+1}-\sum_{i=0}^{k-1}C_{k+1}^iS_{n,i}}{k+1} Sn,k=k+1(n+1)k+1i=0k1Ck+1iSn,i
我们有了这个递推式即可在 Θ ( B 2 log ⁡ 2 P ) \Theta(B^2\log_2P) Θ(B2log2P)的时间内求出我们所需的 S S 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;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值