Let a_1, a_2, ..., a_n be a given set of integers. Denote by F_{ik}~(i \ge k) the sum of all possible products of integers chosen from the first integers a_1, ..., a_i. Let us construct the following table of F_{ik} values:
For four numbers, we obtain:
F_{4,1} = a_1 + a_2 + a_3 + a_4;
F_{4,2} = a_1a_2 + a_1a_3 + a_1a_4 + a_2a_3 + a_2a_4 + a_3a_4;
F_{4,3} = a_1a_2a_3 + a_1a_2a_4 + a_1a_3a_4 + a_2a_3a_4;
F_{4,4} = a_1a_2a_3a_4;
The following recurrence relations hold:
For example,
F_{3,2} = F_{2,2} + F_{2,}1 \cdot a_3 = a_1a_2 + (a_1 + a_2) \cdot a_3 = a_1a_2 + a_1a_3 + a_2a_3;
F_{4,3} = F_{3,3} + F_{3,2} \cdot a_4 = a_1a_2a_3 + (a_1a_2 + a_1a_3 + a_2a_3) \cdot a_4 =
The values of each subsequent row are computed based on the values of the previous row, so it is sufficient to store a single linear array of size up to . The recalculation of the -th row should be performed from the end: first compute F_{ii}, then F_{i(i-1)}, and so on down to F_{i1}. All computations must be performed modulo .
Example
Consider the first test case. We'll construct two tables: in the first table, computations are performed without the modulo, and in the second table, computations are performed modulo m = 10.
For example,
F_{4,2} = F_{3,2} + F_{3,1} \cdot 4 = 11 + 6 \cdot 4 = 35;
F_{4,3} = F_{3,3} + F_{3,2} \cdot 4 = 6 + 11 \cdot 4 = 50;
The answer is the maximum value in the fourth row of the second table.
Algorithm implementation
Declare a linear array , where the values of F_{ik} will be recomputed.
long long d[1000];Read the number of elements and the value . For each input test case, the array is initially cleared. The first number a_1 is stored in .
while (scanf("%lld %lld",&n,&m), n + m > 0)
{
memset(d,0,sizeof(d));
scanf("%lld",&d[0]);Next, read the value x = a_{i+1}~(1 \le i < n) and recalculate the values of F_{ik} for k = i, i - 1, ..., 1 using the recurrence formulas given above. All computations are performed modulo .
for (i = 1; i < n; i++)
{
scanf("%lld",&x);
d[i] = (d[i-1] * x) % m;
for (j = i - 1; j > 0; j--)
d[j] = (d[j-1] * x + d[j]) % m;
d[0] = (d[0] + x) % m;
}Find the maximum value among the elements of the array and store it in the variable .
res = 0;
for (i = 0; i < n; i++)
if (d[i] > res) res = d[i];Print the answer.
printf("%lld\n",res);
}