bzoj35163516: 国王奇遇记加强版(递推)
Posted heyuhhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj35163516: 国王奇遇记加强版(递推)相关的知识,希望对你有一定的参考价值。
题意:
求(displaystyle sum_{i=1}^n i^mm^i,nleq 10^9,mleq 1000)。
思路:
(m)比较小,考虑从(m)入手进行递推:
设(f(j)=sum_{i=1}^ni^jm^i),则(mf(j)=sum_{i=1}^ni^jm^{i+1})。
接下来就是推式子时间:
[egin{aligned}
(1-m)f(j)=&sum_{i=1}^ni^jm^i-sum_{i=1}^ni^jm^{i+1} =&sum_{i=0}^{n-1}(i+1)^jm^{i+1}-sum_{i=0}^{n-1}i^jm^{i+1}-n^jm^{n+1} =&sum_{i=0}^{n-1}((i+1)^j-i^j)m^{i+1}-n^jm^{n+1} =&sum_{i=0}^{n-1}(sum_{k=0}^j{jchoose k}i^k-i^j)m^{i+1}-n^jm^{n+1} =&sum_{i=0}^{n-1}sum_{k=0}^{j-1}{jchoose k}i^km^{i+1}-n^jm^{n+1} =&sum_{k=0}^{j-1}{jchoose k}sum_{i=0}^{n-1}i^km^{i+1}-n^jm^{n+1} =&sum_{k=0}^{j-1}{jchoose k}msum_{i=0}^{n-1}i^km^{i}-n^jm^{n+1} =&sum_{k=0}^{j-1}{jchoose k}m(sum_{i=1}^ni^km^i+(k==0)-n^km^n)-n^jm^{n+1} =&sum_{k=0}^{j-1}{jchoose k}m(f(k)+(k==0)-n^km^n)-n^jm^{n+1}\end{aligned}
]
式子中需要注意的一点就是,当(k=i=0)时,有(0^0=1),这是定义,所以我们要特判一下然后加上一个(1)。
其它就没什么好说的了。感觉这种递推构造两个式子相减还是挺常见的。(就是想不到)
代码如下:
/*
* Author: heyuhhh
* Created Time: 2020/4/17 19:45:42
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1000 + 5, MOD = 1e9 + 7;
int qpow(ll a, ll b) {
ll res = 1;
while(b) {
if(b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
int n, m;
int f[N], C[N][N];
int pown[N];
void run() {
cin >> n >> m;
if(m == 1) {
cout << 1ll * n * (n + 1) / 2 % MOD << ‘
‘;
return;
}
pown[0] = 1;
for(int i = 1; i <= m; i++) pown[i] = 1ll * pown[i - 1] * n % MOD;
int powm = qpow(m, n), powm1 = qpow(m, n + 1);
int inv = qpow(1 - m + MOD, MOD - 2);
f[0] = 1ll * m * (1 - powm + MOD) % MOD * inv % MOD;
for(int i = 0; i < N; i++) {
C[i][0] = 1;
for(int j = 1; j <= i; j++) {
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
}
}
for(int i = 1; i <= m; i++) {
f[i] = (MOD - 1ll * pown[i] * powm1 % MOD) % MOD;
for(int k = 0; k < i; k++) {
int res = 1ll * C[i][k] * m % MOD * ((f[k] + (k == 0) - 1ll * powm * pown[k] % MOD + MOD) % MOD) % MOD;
f[i] = (f[i] + res) % MOD;
}
f[i] = 1ll * f[i] * inv % MOD;
}
cout << f[m] << ‘
‘;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
以上是关于bzoj35163516: 国王奇遇记加强版(递推)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 3157 & bzoj 3516 国王奇遇记 —— 推式子
bzoj 3157 && bzoj 3516 国王奇遇记——推式子