The problem requires repeatedly finding the minimum on a segment of an array that does not change after generation. The number of queries reaches 10^7, so each query must be processed in . To do this, we use a sparse table — a static data structure for the RMQ (Range Minimum Query) problem.
Building the table. For each position and each such that i + 2^j - 1 \le n, the cell mas[i][j] stores the index of the minimum element on the segment [i; i + 2^j - 1] of length 2^j. For j = 0 the segment consists of one element, so mas[i][0] = i.
For j > 0, split the segment of length 2^j into two halves of length 2^{j-1}: [i; i + 2^{j-1} - 1] and [i + 2^{j-1}; i + 2^j - 1]. The indices of the minimums on the halves have already been computed — they are mas[i][j - 1] and mas[i + 2^{j-1}][j - 1]:
The minimum of the whole segment equals the smaller of the two minimums of the halves. Therefore, mas[i][j] equals whichever of the indices mas[i][j - 1] and mas[i + 2^{j-1}][j - 1] points to the smaller array element. The table is filled in increasing order of and contains O(n \log n) cells.
Answering a query. Suppose we need to find the minimum on the segment . Let k = \lfloor \log_2(v - u + 1) \rfloor be the exponent of the largest power of two not exceeding the length of the segment. The segment of length 2^k starting at and the segment of length 2^k ending at together completely cover , since 2 \cdot 2^k > v - u + 1:
These segments may overlap, but this does not matter for the minimum: an element counted twice does not change the result (unlike, for example, the sum). Therefore, the minimum on equals the smaller of the elements a[mas[u][k]] and a[mas[v - 2^k + 1][k]], and a query is processed in .
The bounds and of the generated queries may come in any order, so before executing a query we swap them if necessary.
Complexity. Building the table takes O(n \log n), and each query takes . The overall complexity is O(n \log n + m). With m \le 10^7, it is precisely the query time that makes it possible to fit into the time limit.
Example
Consider the example: n = 10, m = 8, a_1 = 12345. The generated array coincides with the array given in the problem statement. The table for it is shown below. The cells contain the indices of the minimum elements; a dash means that the segment goes beyond the array.
\boldsymbol{j \setminus i} | ||||||||||
— | ||||||||||
— | — | — | ||||||||
— | — | — | — | — | — | — |
For example, mas[3][2] = 5: on the segment , the minimum element is a_5 = 1565158. The value mas[2][3] = 2 is obtained from mas[2][2] = 2 and mas[6][2] = 8, since a_2 = 305498 < a_8 = 570265.
The first query: u_1 = 3, v_1 = 9. The length of the segment is , so k = 2. The segment is covered by the segments and , for which mas[3][2] = 5 and mas[6][2] = 8. Since a_8 = 570265 < a_5 = 1565158, the answer is ans_1 = 570265.
The parameters of the second query:
Since u_2 > v_2, the bounds are swapped, and the minimum on the segment is computed.
All queries are listed in the table:
\boldsymbol{u_i} | \boldsymbol{v_i} | segment | \boldsymbol{ans_i} | |
The last query has the parameters u_8 = 5, v_8 = 3, and its answer is ans_8 = 1565158. These are exactly the values that are printed. Note that the original values u_8 and v_8 are printed, not the ordered bounds of the segment.
Algorithm implementation
The elements of the array (n \le 10^5) are stored starting from index . The sparse table is stored in the array : mas[i][j] is the index of the minimum element on the segment [i; i + 2^j - 1]. Since 2^{16} \le 10^5 < 2^{17}, the values of do not exceed , so LOGMAX = 17 is enough for the second dimension.
#define MAX 100001
#define LOGMAX 17
int a[MAX];
int mas[MAX][LOGMAX];The function check swaps the values of and if u > v, so that u \le v. The parameters are passed by reference.
void check(int &u, int &v)
{
int temp;
if (u > v) temp = u, u = v, v = temp;
}The function RMQ_nlogn builds the sparse table.
void RMQ_nlogn(void)
{
int i, j;First, mas[i][0] = i for all .
for (i = 1; i <= n; i++) mas[i][0] = i;Then, for each while 2^j \le n, and for each such that the segment [i; i + 2^j - 1] does not go beyond the array, choose from mas[i][j - 1] and mas[i + 2^{j-1}][j - 1] the index of the smaller element.
for (j = 1; (1 << j) <= n; j++)
for (i = 1; i + (1 << j) - 1 <= n; i++)
if (a[mas[i][j - 1]] < a[mas[i + (1 << (j - 1))][j - 1]])
mas[i][j] = mas[i][j - 1];
else mas[i][j] = mas[i + (1 << (j - 1))][j - 1];
}The function q returns the index of the minimum element on the segment . Compute k = \lfloor \log_2(j - i + 1) \rfloor and compare the minimums of two segments of length 2^k: [i; i + 2^k - 1] and [j - 2^k + 1; j].
int q(int i, int j)
{
int k = (int)(log(1.0*j - i + 1) / log(2.0));
int res = mas[i][k];
if (a[mas[j - (1<<k) + 1][k]] < a[res])
res = mas[j - (1<<k) + 1][k];
return res;
}The main part of the program. Read , , the first array element a_1, and the parameters of the first query and .
scanf("%d %d",&n,&m);
scanf("%d %d %d",&a[1],&u,&v);Generate the elements a_2, a_3, \ldots, a_n using the formula from the problem statement. The product 23 \cdot a_i does not exceed 23 \cdot 16714589 \approx 3.8 \cdot 10^8 and fits into the type.
for(i = 2; i <= n; i++)
a[i] = (23 * a[i-1] + 21563) % 16714589;Build the sparse table .
RMQ_nlogn();Process the queries one by one.
for (i = 1; i <= m; i++)
{Copy the bounds of the current query into and and, if necessary, order them with the function check. The values and themselves are not changed: the parameters of the next query are computed from them, and they are what is printed in the answer.
u1 = u; v1 = v; check(u1,v1);Find the minimum element on the segment [u1; v1].
ans = a[q(u1,v1)];If the query is not the last one, compute the parameters of the next query using the formulas from the problem statement.
if (i < m)
{
u = ((17*u + 751 + ans + 2*i) % n) + 1;
v = ((13*v + 593 + ans + 5*i) % n) + 1;
}
}Print the parameters of the last query and its answer.
printf("%d %d %d\n",u,v,ans);