k-Tree
Source: https://codeforces.com/problemset/problem/431/C
Let .
A path from the root is determined uniquely by the sequence of edge weights used along the path. Hence the problem is equivalent to counting finite sequences
such that
and
with at least one .
Let be the number of such sequences with total sum , using parts from to . Let be the number of such sequences with total sum , using only parts from to .
We define the base case
for the empty sequence, and
whenever .
For , consider the last term of a sequence counted by . If the last term is , where , then the previous terms must form a sequence with sum . Therefore
Similarly, a sequence counted by may only use terms smaller than . Hence its last term may be any with , giving
Now counts all sequences summing to , without enforcing the condition that some edge has weight at least . The sequences that fail this condition are exactly those in which every term is less than , and these are counted by .
Thus the required number of paths is
Since the answer is required modulo , the final answer is
and can be defined by a shared counting function count.
using ll = long long;
const ll MOD = 1e9 + 7;
ll count(int n, int max) {
vector<ll> dp(n + 1, 0);
dp[0] = 1;
for (int s = 1; s <= n; ++s) {
for (int i = 1; i <= max && i <= s; ++i) {
dp[s] = (dp[s] + dp[s - i]) % MOD;
}
}
return dp[n];
}
Where we can set and .
void solve() {
int n, k, d;
cin >> n >> k >> d;
ll A = count(n, k);
ll B = count(n, d - 1);
cout << (A - B + MOD) % MOD << '\n';
}
Full cp-grade code
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
const ll MOD = 1e9 + 7;
#pragma GCC optimize("Ofast", "inline", "fast-math", "unroll-loops", \
"no-stack-protector", "-ffast-math")
#pragma GCC target( \
"sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native", "f16c")
static const bool Booster = []() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return true;
}();
auto init = []() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
return 'c';
}();
ll count(int n, int max) {
vector<ll> dp(n + 1, 0);
dp[0] = 1;
for (int s = 1; s <= n; ++s) {
for (int i = 1; i <= max && i <= s; ++i) {
dp[s] = (dp[s] + dp[s - i]) % MOD;
}
}
return dp[n];
}
void solve() {
int n, k, d;
cin >> n >> k >> d;
ll A = count(n, k);
ll B = count(n, d - 1);
cout << (A - B + MOD) % MOD << '\n';
}
int main() {
solve();
return 0;
}