CF712D
Sol
不难想到暴力 DP,复杂度 \(O(tk^2)\),无法通过。
观察转移方程,注意到贡献到每个点的状态一定是连续的区间,那么用前缀和维护就好了。
偏移量可以设置的大一些以防 RE。
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
if (y > x) return x = y,true;
return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
if (y < x) return x = y,true;
return false;
}
LL power (LL a,LL b,LL p) {
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 400010,MOD = 1e9 + 7;
int a,b,k,n;
LL f[2][N],g[N];
LL ans1[N],ans2[N];
LL sum (int l,int r) {
LL ans = g[min (r,N - 1)];
if (l - 1 >= 0) ans = (ans - g[l - 1] + MOD) % MOD;
return ans;
}
void solve (int a,LL ans[N]) {
memset (f,0,sizeof (f)),memset (g,0,sizeof (g));
f[0][a + (int)2e5] = 1;
for (int i = 1;i <= n;i++) {
memset (f[i & 1],0,sizeof (f[i & 1]));
for (int j = 0;j < N;j++) g[j] = f[i - 1 & 1][j];
for (int j = 1;j < N;j++) (g[j] += g[j - 1]) %= MOD;
for (int j = 0;j < N;j++) f[i & 1][j] = sum (j - k,j + k);
}
for (int i = 0;i < N;i++) ans[i] = f[n & 1][i];
}
void mian () {
cin >> a >> b >> k >> n;
solve (a,ans1),solve (b,ans2);
for (int i = 1;i < N;i++) (ans2[i] += ans2[i - 1]) %= MOD;
LL ans = 0;
for (int i = 1;i < N;i++) (ans += ans1[i] * ans2[i - 1] % MOD) %= MOD;
cout << ans << endl;
}
int main () {
int T = 1;
// cin >> T;
while (T--) mian ();
return 0;
}

浙公网安备 33010602011771号