Por Samyra Almeida
Para resolver esse problema é necessário conhecimento sobre a técnica de sweep line e a estrutura da BIT (ou Binary Indexed Tree).
Segundo o enunciado temos que, dados dois pontos e
e sendo
, temos que
não domina
se
.
Agora vamos utilizar a ideia do sweep line, primeiro iremos ordenar todos os pontos pela coordenada . Com isso, note que dado qualquer conjunto válido
, sabemos que
e
. Calculando a quantidade de conjuntos válidos até um determinado ponto
temos que
.
Para calcularmos a quantidade de conjuntos válidos para o ponto de forma eficiente iremos utilizar uma estrutura de dados chamada BIT (ou Binary Indexed Tree) na coordenada
em que cada índice
da BIT guarda a quantidade de conjuntos válidos no qual
faz parte. De inicio a BIT estará vazia, mas iremos adicionando os conjuntos conforme o nosso algoritmo estiver rodando. Para descobrirmos quantos conjuntos válidos
participa basta consultarmos a soma de
até
, onde
é igual a maior coordenada
dentre todos os pontos presentes em
, fazendo
. Após isso, iremos atualizar a
fazendo
. Enfim ao rodarmos esse algoritmo para todos os
pontos temos que a resposta final será igual ao
.
Segue o código para maior entendimento:
This file contains 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> | |
using namespace std; | |
const int maxn = 1e5+10, mod = 1e9+7; | |
int n, m, bit[maxn], quantidade[maxn]; | |
struct point{ | |
int x, y; | |
bool operator<(const point& o) const{ | |
if(x != o.x) return x < o.x; | |
return y < o.y; | |
} | |
} p[maxn]; | |
void add(int i, int v){ | |
while(i) | |
{ | |
bit[i] = (bit[i]%mod + v)%mod; | |
i-=(i&-i); | |
} | |
} | |
int sum(int i) | |
{ | |
int soma = 0; | |
for(; i <= m ; i += (i&-i)) | |
{ | |
soma = (soma%mod +bit[i])%mod; | |
} | |
return soma; | |
} | |
int main() | |
{ | |
cin >> n; | |
for(int i = 1 ; i <= n ; ++i) | |
{ | |
cin >> p[i].x >> p[i].y; | |
m = max(m, p[i].y); | |
} | |
sort(p + 1, p + n + 1); | |
int resp = 0; | |
for(int i = 1 ; i <= n ; ++i) | |
{ | |
quantidade[i] = (sum(p[i].y + 1)%mod + 1)%mod; | |
add(p[i].y, quantidade[i]); | |
resp = (resp%mod + quantidade[i])%mod; | |
} | |
cout << resp << "\n"; | |
return 0; | |
} |