G. The Maximum Prefix time limit per test1 second...
Creado el: 29 de abril de 2025
Respondido usando O4 Mini High por Chat01
Creado el: 29 de abril de 2025
Respondido usando O4 Mini High por Chat01
G. The Maximum Prefix
time limit per test1 second
memory limit per test256 megabytes
You're going to generate an array a
with a length of at most n
, where each ai
equals either 1
or −1
.
You generate this array in the following way.
First, you choose some integer k
(1≤k≤n
), which decides the length of a
.
Then, for each i
(1≤i≤k
), you set ai=1
with probability pi
, otherwise set ai=−1
(with probability 1−pi
).
After the array is generated, you calculate si=a1+a2+a3+…+ai
. Specially, s0=0
. Then you let S
equal to maxi=0ksi
. That is, S
is the maximum prefix sum of the array a
.
You are given n+1
integers h0,h1,…,hn
. The score of an array a
with maximum prefix sum S
is hS
. Now, for each k
, you want to know the expected score for an array of length k
modulo 109+7
.
Input
Each test contains multiple test cases. The first line contains a single integer t
(1≤t≤5000
) — the number of test cases. Their description follows.
The first line contains an integer n
(1≤n≤5000
).
Then for the following n
lines, each line contains two integers xi
and yi
(0≤xi<109+7
, 1≤yi<109+7
, xi≤yi
), indicating pi=xiyi
.
The next line contains n+1
integers h0,h1,…,hn
(0≤hi<109+7
).
It is guaranteed that the sum of n
over all test cases does not exceed 5000
.
Output
For each test case, output n
integers in one single line, the i
-th of which denotes the expected score for an array of length i
, modulo 109+7
.
Formally, let M=109+7
. It can be shown that the answer can be expressed as an irreducible fraction pq
, where p
and q
are integers and q≢0(modM)
. Output the integer equal to p⋅q−1modM
. In other words, output such an integer x
that 0≤x<M
and x⋅q≡p(modM)
.
Example
Input
4
2
1 2
1 2
1 2 3
3
1 3
1 4
5 5
1 1 1 1
3
2 5
4 6
0 2
4 3 2 1
5
5 6
5 7
1 6
1 3
4 7
9 0 4 5 2 4
output
500000005 750000007
1 1 1
200000005 333333339 333333339
500000005 880952391 801587311 781746041 789304620
Note
In the first test case, if we choose k=1
, there are 2
possible arrays with equal probabilities: [1]
and [−1]
. The S
values for them are 1
and 0
. So the expected score is 12h0+12h1=32
. If we choose k=2
, there are 4
possible arrays with equal probabilities: [1,1]
, [1,−1]
, [−1,1]
, [−1,−1]
, and the S
values for them are 2,1,0,0
. So the expected score is 12h0+14h1+14h2=74
.
In the second test case, no matter what the S
value is, the score is always 1
, so the expected score is always 1
.
To solve this in , we use a “reverse-DP on contributions” trick. First, observe that if you ran the straightforward DP for the full length
then the expected score for length would be
But the same linear recurrence applies if you stop at any earlier position (i.e.\ take as your “initial” condition). By linearity, the answer for length is exactly the coefficient with which that “” appears in the full-length sum. If you call that coefficient , you get the following very simple DP on :
Below is a concise C++ implementation:
cpp#include <bits/stdc++.h> using namespace std; static const int MOD = 1000000007; // Fast exponentiation to compute a^(MOD-2) % MOD long long modexp(long long a, long long b = MOD-2) { long long r = 1 % MOD; while (b > 0) { if (b & 1) r = r * a % MOD; a = a * a % MOD; b >>= 1; } return r; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n; cin >> n; vector<long long> p(n+1), q(n+1); for (int i = 1; i <= n; i++) { long long x, y; cin >> x >> y; // p_i = x * inv(y) % MOD p[i] = x * modexp(y) % MOD; // q_i = 1 - p_i (mod MOD) q[i] = (1 - p[i] + MOD) % MOD; } // Read the h[0..n] array vector<long long> h(n+1); for (int i = 0; i <= n; i++) { cin >> h[i]; } // We'll keep two rolling rows of g[*][*]: vector<long long> cur(n+2), nxt(n+2); // Base: g[1][j] = h[j] for (int j = 0; j <= n; j++) { cur[j] = h[j]; } vector<long long> ans(n+1); // Build g row by row for (int i = 1; i <= n; i++) { // Compute g[i+1][j] = p_i*cur[j+1] + q_i*cur[max(j-1,0)] for (int j = 0; j <= n; j++) { long long t1 = (j+1 <= n ? cur[j+1] : 0); long long t2 = (j > 0 ? cur[j-1] : cur[0]); nxt[j] = (p[i] * t1 + q[i] * t2) % MOD; } ans[i] = nxt[0]; // answer for length i swap(cur, nxt); } // Output for (int i = 1; i <= n; i++) { cout << ans[i] << (i==n? '\n':' '); } } return 0; }
Complexity.