【AGC009E】永遠の平均
フェイス質問
問題の解決策
不滅のタイトルを.JPG
我々は、のように動作する\(K \)各ノードが正しい値である木、すべてのリーフノード(コ\(N + m個の\) a)が(0 \)を\または\(1 \) 。
合併に代わってすべてのノードのリーフノード以外で、重量はそれらの平均です。
スタートセット(0 \)\を深ポイントはそれぞれ\(X_1、X_2 ... x_nに関する\)、\ (1 \)の深さ\(Y_1、Y_M Y_2 ... \) 。
次いで、根の重量\(\ SUM(\ FRAC 1K)Y_I ^ {} \) 、我々はすべての点の右側にある値を変更する場合は\(1 \)は、根の重量もあった\(1 \) 、そこである\(\ SUM(\ FRAC 1K)X_I ^} +は{\ SUM(\ FRAC 1K)} = ^ {Y_I。1 \) 、この条件が満たされる場合、ソリューションを構築することができるであろう。
その問題は、数に変換される\(Zの\)のように書くことができる\(N- \)\((\ FRAC 1K)^ X \)、\ (1-Z \)のように書くことができる\(m個\)\(( \ FRAC 1K)^ Y \)は、フォームを追加しました。
我々は\(Z \)として表現される\((0.c_1c_2 ...)_ K \) 、次いで、もしキャリー\(\ C = SUM m個の\) 、その後キャリー減算を続ける\(K-1を\) 、次いで(\ \ C = SUM mを(\ BMOD \ ;. 1-K)\) 。
仮定が小数である\(LEN \)ビット、\(1-Zの\)は、とすべきである\((LEN-1)( K-1)+ K-和C = LEN \(K-1) - \和。1 + C \) 。
次に、設定\(F_ {I、J} \) セクションを表し\(Iは\)ビット、及び現在のための\(J \)の端部がないため、プログラムナンバーができるが(0 \)\ように開くように、覚えている最後の1次元かどうか\(0 \) 。
(問題解決参照litbleの多数)
コード
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int Mod = 1e9 + 7;
const int MAX_N = 2e3 + 5;
int N, M, K, ans;
int f[MAX_N << 1][MAX_N][2], s[MAX_N];
int main () {
cin >> N >> M >> K;
f[0][0][0] = 1;
for (int i = 1; i <= N + M; i++) {
s[0] = (f[i - 1][0][0] + f[i - 1][0][1]) % Mod;
for (int j = 1; j <= N; j++)
s[j] = (s[j - 1] + (f[i - 1][j][0] + f[i - 1][j][1]) % Mod) % Mod;
for (int j = 0; j <= N; j++) {
f[i][j][0] = (f[i - 1][j][0] + f[i - 1][j][1]) % Mod;
if (j) f[i][j][1] = (s[j - 1] - (j - K >= 0 ? s[j - K] : 0) + Mod) % Mod;
}
for (int j = 0; j <= N; j++)
if (j % (K - 1) == N % (K - 1) &&
(i * (K - 1) - j + 1) % (K - 1) == M % (K - 1) &&
i * (K - 1) - j + 1 <= M)
ans = (ans + f[i][j][1]) % Mod;
}
printf("%d\n", ans);
return 0;
}