Let ways(x, y) denote the number of paths on a grid from cell to cell (1 + x, 1 + y). Then
The number of paths from cell to cell that pass through a special cell is equal to ways(x - 1, y - 1) \cdot ways(n - x, m - y). Multiplying this number by gives the total power of all paths passing through cell .
It remains to sum the powers of all paths passing through the special cells. The answer will be equal to the sum:
Example
In the given example, k = 2 special cells are specified.
Exactly one path passes through the cell with power .
Exactly one path passes through the cell with power .
Thus, the total power is 4 + 7 = 11.
Algorithm implementation
Declare the arrays:
contains the factorials of numbers modulo ,
factinv contains the inverse values of these factorials modulo :
#define MAX 800001
ll fact[MAX], factinv[MAX];The pow function computes the power of a number modulo : x^n~mod~p.
ll pow(ll x, ll n, ll p)
{
if (n == 0) return 1;
if (n % 2 == 0) return pow((x * x) % p, n / 2, p);
return (x * pow(x, n - 1, p)) % p;
}The inverse function finds the number that is the modular inverse of with respect to a prime modulo . Since is a prime number, by Fermat's Little Theorem the following holds:
This can be rewritten as (x \cdot x^{p-2})~mod~p = 1, from which it follows that the modular inverse of is x^{p-2}~mod~p.
ll inverse(ll x, ll p)
{
return pow(x, p - 2, p);
}The Cnk function computes the binomial coefficient using the formula:
ll Cnk(int n, int k)
{
return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
}The ways function calculates the number of paths on an n \times m grid from cell to cell . Since any path between these points has length n + m and contains exactly horizontal steps, the number of paths is equal to C_{n+m}^m.
ll ways(int n, int m)
{
return Cnk(n + m, m);
}The main part of the program. Fill the arrays of factorials and inverse factorials factinv.
fact[0] = 1;
for (i = 1; i < MAX; i++)
fact[i] = (fact[i - 1] * i) % MOD;
factinv[0] = 1;
for (i = 1; i < MAX; i++)
factinv[i] = inverse(fact[i], MOD);Process the tests sequentially.
scanf("%d", &tests);
while (tests--)
{Read the data for the current test.
scanf("%d %d %d", &n, &m, &k);Store the total obtained power in the variable .
res = 0;Process the special cells.
for (i = 0; i < k; i++)
{
scanf("%d %d %d", &x, &y, &p);
res = (res + (ways(x - 1, y - 1) *
ways(n - x, m - y)) % MOD * p) % MOD;
}Print the answer for the current test.
printf("%lld\n", res);
}