[usOJ3384]幂和

题目

传送门 to usOJ

题目描述
对于给定的 A , B , C , D , P A, B, C, D, P A,B,C,D,P ,求 ∑ i = A B ∑ j = C D j i \sum_{i=A}^{B}\sum_{j=C}^{D}j^i i=ABj=CDji P P P 取模的值。

保证 P P P 是一个质数

输入格式
输入一行五个整数 A , B , C , D A, B, C, D A,B,C,D P P P

输出格式
输出一行,表示你的答案。

数据范围与约定
对于 15 % 15\% 15% 的数据, A , B , C , D ≤ 1000 A, B, C, D ≤ 1000 A,B,C,D1000

对于 30 % 30\% 30% 的数据, C , D ≤ 500000 C, D ≤ 500000 C,D500000

对于另外 10 % 10\% 10% 的数据, A = B A=B A=B

对于 50 % 50\% 50% 的数据, C , D ≤ 1 0 7 C, D ≤ 10^7 C,D107

对于 70 % 70\% 70% 的数据, P ≤ 1 0 7 P ≤ 10^7 P107

对于 100 % 100\% 100% 的数据, 1 ≤ C ≤ D ≤ 1 0 18 , 1 ≤ A ≤ B ≤ 3000 , B + 1 < P ≤ 1 0 9 1 ≤ C ≤ D ≤ 10^{18}, 1 ≤ A ≤ B ≤ 3000, B+1 < P ≤ 10^9 1CD1018,1AB3000,B+1P109

思路

传说中的毒瘤数学题!

这道题显然是个数学结论题。考虑怎么处理 S k = ∑ i = 0 n i k S_k=\sum_{i=0}^{n}i^k Sk=i=0nik 。这样搞——

警告:下面是该死的真·数学变换

∵ S k + 1 = ∑ i = 0 n i k + 1 ∴ S k + 1 + ( n + 1 ) k + 1 = ∑ i = 0 n ( i + 1 ) k + 1 \because S_{k+1}=\sum_{i=0}^{n}i^{k+1}\\ \therefore S_{k+1}+(n+1)^{k+1}=\sum_{i=0}^{n}(i+1)^{k+1} Sk+1=i=0nik+1Sk+1+(n+1)k+1=i=0n(i+1)k+1

二项式展开,得到

S k + 1 + ( n + 1 ) k + 1 = ∑ i = 0 n ∑ j = 0 k + 1 C k + 1 j i j = ∑ j = 0 k + 1 C k + 1 j ∑ i = 0 n i j \begin{aligned}S_{k+1}+(n+1)^{k+1}&=\sum_{i=0}^{n}\sum_{j=0}^{k+1}C_{k+1}^j i^j\\&=\sum_{j=0}^{k+1}C_{k+1}^j\sum_{i=0}^ni^j \end{aligned} Sk+1+(n+1)k+1=i=0nj=0k+1Ck+1jij=j=0k+1Ck+1ji=0nij

j = k + 1 j=k+1 j=k+1 的那一项提出来,得到

S k + 1 + ( n + 1 ) k + 1 = C k + 1 k + 1 ∑ i = 0 n i k + 1 + ∑ j = 0 k C k + 1 j ∑ i = 0 n i j = S k + 1 + ∑ j = 0 k C k + 1 j ∑ i = 0 n i j \begin{aligned}S_{k+1}+(n+1)^{k+1}&=C_{k+1}^{k+1}\sum_{i=0}^{n}i^{k+1}+\sum_{j=0}^kC_{k+1}^j\sum_{i=0}^ni^j\\&=S_{k+1}+\sum_{j=0}^kC_{k+1}^j\sum_{i=0}^ni^j \end{aligned} Sk+1+(n+1)k+1=Ck+1k+1i=0nik+1+j=0kCk+1ji=0nij=Sk+1+j=0kCk+1ji=0nij

于是可以消除掉 S k + 1 S_{k+1} Sk+1 ,得到

( n + 1 ) k + 1 = ∑ j = 0 k C k + 1 j ∑ i = 0 n i j (n+1)^{k+1}=\sum_{j=0}^kC_{k+1}^j\sum_{i=0}^ni^j (n+1)k+1=j=0kCk+1ji=0nij

于是我们把 j = k j=k j=k 的那一项又拿出来,得到

( n + 1 ) k + 1 = C k + 1 k ∑ i = 0 n i k + ∑ j = 0 k − 1 C k + 1 j ∑ i = 0 n i j = ( k + 1 ) S k + ∑ j = 0 k − 1 C k + 1 j ∑ i = 0 n i j \begin{aligned}(n+1)^{k+1}&=C_{k+1}^k\sum_{i=0}^ni^k+\sum_{j=0}^{k-1}C_{k+1}^j\sum_{i=0}^ni^j\\ &=(k+1)S_k+\sum_{j=0}^{k-1}C_{k+1}^j\sum_{i=0}^ni^j \end{aligned} (n+1)k+1=Ck+1ki=0nik+j=0k1Ck+1ji=0nij=(k+1)Sk+j=0k1Ck+1ji=0nij

∴ ( k + 1 ) S k = ( n + 1 ) k + 1 − ∑ j = 0 k − 1 C k + 1 j ∑ i = 0 n i j \therefore (k+1)S_k=(n+1)^{k+1}-\sum_{j=0}^{k-1}C_{k+1}^j\sum_{i=0}^ni^j (k+1)Sk=(n+1)k+1j=0k1Ck+1ji=0nij

∴ S k = ( k + 1 ) − 1 [ ( n + 1 ) k + 1 − ∑ j = 0 k − 1 C k + 1 j S j ] \therefore S_k=(k+1)^{-1}[(n+1)^{k+1}-\sum_{j=0}^{k-1}C_{k+1}^jS_j] Sk=(k+1)1[(n+1)k+1j=0k1Ck+1jSj]

警报解除!

然后这就是一个 O ( k 2 ) \mathcal O(k^2) O(k2) 的递推了。剩下的事情,就是前缀和做差。

代码

代码实现是比较简单的,这里就不给出了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值