题目大意
给出 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=0∑n(i+1)k+1=i=0∑nj=0∑k+1Ck+1jij=i=0∑k+1Ck+1ij=0∑nji=i=0∑kCk+1ij=0∑nji+i=0∑nik+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=0∑kCk+1ij=0∑nji
( 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=0∑k−1Ck+1ij=0∑nji+(k+1)i=0∑nik
( 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=0∑k−1Ck+1ij=0∑nji=(k+1)i=0∑nik
∑ 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=0∑nik=k+1(n+1)k+1−∑i=0k−1Ck+1i∑j=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+1−∑i=0k−1Ck+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;
}