Comentário por Murilo Maeda
Nesse problema há duas dificuldades principais: o tamanho grande da matriz, então não podemos nem percorrê-la nem mantê-la em uma matriz, e a forma desorganizada que os números aparecem na matriz, não há um padrão que nos permita concluir coisas sobre a posição e organização de números na matriz.
Para resolver o primeiro problema, basta simplesmente não mantermos a matriz. Vamos manter somente os vetores
e
e quando precisarmos de um valor, só somamos os valores necessários de
e
.
Agora, vamos resolver o segundo problema.
Note que, como queremos encontrar os
menores números, a posição deles na matriz não importa. Por isso, podemos ordenar os vetores
e
, do menor para o maior e formar a matriz
na qual
. Agora, temos duas propriedades dessa matriz: em uma mesma linha, se a percorrermos de
a
, os valores estarão dispostos em ordem não decrescente. O mesmo ocorre quando percorremos uma coluna de
a
.
A partir disso, vamos analizar o que acontece quando queremos saber quantos valores menores ou iguais a um determinado valor
estão na matriz
. Note que, se encontrarmos em uma determinada linha
o índice
de modo que o valor
é o maior valor maior ou igual a
na linha
, nas linhas com índice menor que
, o maior valor maior ou igual a
vai estar em um índice maior ou igual a
, já que os valores em uma coluna e em uma linha estão em ordem não decrescente. Por isso, para um determinado número
, para descobrir quantos valores menores ou iguais a ele estão na matriz
, podemos simplesmente fazer o seguinte: passamos pela linha n e pegamos
e o somamos no número de valores menores ou iguais a
. Para uma linha
: a percorremos a partir do índice
enquanto os valores forem menores ou iguais a
. Paramos no índice
e somamos
no número de valores menores ou iguais a
.
Com isso, podemos calcular em
quantos valores são menores ou iguais a
na matrisz
. Então, basta fazermos uma busca binária na resposta, tentando encontrar o valor que queremos. Fazemos isso chutando o número da resposta, checando quantos valores são menores ou iguais a ele em
e em seguida comparando esse resultado com
.
Segue o código para maior esclarecimento:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include<bits/stdc++.h> | |
| #define int long long | |
| using namespace std; | |
| const int MAXN = 1e6 + 10; | |
| int x[MAXN],y[MAXN]; | |
| int n,k, maior; | |
| //Calculo para um valor val quantos números menores ou iguais a ele estão na matriz | |
| bool calc(int val) | |
| { | |
| int aux = 0; | |
| int j = 0; | |
| //Passo por cada linha | |
| for(int i = n; i > 0; i–) | |
| { | |
| //Tento aumentar o j. Note que o j não é zerado quando mudo de linha | |
| while(x[i] + y[j + 1] <= val && j < n) | |
| { | |
| j++; | |
| } | |
| //Adiciono J no número de valores menores ou iguais a val na matriz | |
| aux += j; | |
| } | |
| //Comparo com k para a busca binária | |
| if(aux >= k) return true; | |
| return false; | |
| } | |
| //Busca binária na resposta | |
| int bsearch() | |
| { | |
| int ini = x[1] + y[1]; | |
| int fim = maior; | |
| while(ini < fim) | |
| { | |
| int m = (ini + fim)/2; | |
| //Testo se a nossa resposta for m | |
| if(calc(m)) | |
| fim = m; | |
| else | |
| ini = m + 1; | |
| } | |
| return fim; | |
| } | |
| int32_t main() | |
| { | |
| cin.tie(0)->sync_with_stdio(0); | |
| cin >> n >> k; | |
| int ax,bx,cx,mx; cin >> ax >> bx >> cx >> mx; | |
| int ay,by,cy,my; cin >> ay >> by >> cy >> my; | |
| x[1] = ax; | |
| y[1] = ay; | |
| for(int i = 2; i <= n; i++) | |
| { | |
| x[i] = (bx + cx*x[i-1])%mx; | |
| y[i] = (by + cy*y[i-1])%my; | |
| } | |
| //Ordeno os vetores para organizar a matriz | |
| sort(x + 1, x + (n + 1)); | |
| sort(y + 1, y + (n + 1)); | |
| maior = x[n] + y[n]; | |
| cout << bsearch(); | |
| } |
