Solução Avançado Informática - Semana 43

Solução por Frederico Bulhoes

Essa é uma aplicação do algoritmo de contagem de inversões. Ou seja ele quer saber para cada flecha quantas flechas antes estão com distância menor.

Com cuidado para não esquecer o long long podemos implementar esse algoritmo de duas formas: com merge sort ou BIT.

A solução abaixo usa Merge Sort.

Código para melhor entendimento.


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
const ll inf = 0x3fffffffffffffff;
ll merge(vll & v)
{
if (v.size() == 1) return 0;
int sz = (int)v.size();
vll a;
vll b;
for (int i = 0; i < sz/2; i++) a.push_back(v[i]);
for (int i = sz/2 ; i < sz; i++) b.push_back(v[i]);
ll an = merge(a);
an += merge(b);
a.push_back(-inf);
b.push_back(-inf);
int i = 0, j = 0;
for (int ind = 0; ind < sz; ind++) {
if (a[i] <= b[j]) {
v[ind] = b[j];
j++;
an += (ll)a.size() - (ll)i - 1;
} else if (a[i] > b[j]) {
v[ind] = a[i];
i++;
}
}
return an;
}
int main()
{
int n;
cin >> n;
vll v;
ll a, b;
for (int i = 0; i < n; i++) {
cin >> a >> b;
v.push_back(a*a + b*b);
}
ll resp = merge(v);
cout << resp << "\n";
return 0;
}

view raw

arcoeflecha.cpp

hosted with ❤ by GitHub

Solução com BIT


//solucao de Leonardo Paes
#include <bits/stdc++.h>
using namespace std;
#define MAXN 600100
#define PB push_back
typedef long long ll;
int tree[MAXN], vet[MAXN], n;
vector< pair< ll , ll> > m;
int sum(int x){
int s=0;
while(x>0){
s+=tree[x];
x-=(x&-x);
}
return s;
}
void update(int x, int k){
while(x<=n){
tree[x]+=k;
x+=(x&-x);
}
}
bool compara(pair<long long, long long> a, pair<long long ,long long> b){
return a.first < b.first;
}
bool compara2(pair<long long,long long> a, pair<long long ,long long> b){
return a.second < b.second;
}
int main(){
ios_base::sync_with_stdio(false);cin.tie(NULL);
long long resp=0;
cin >> n;
for(int i=1; i<=n; i++){
long long a, b;
cin >> a >> b;
m.PB(make_pair(a*a + b*b, i));
}
sort(m.begin(), m.end(), compara);
int k=1;
for(int i=0; i<n; i++){
if(m[i].first==m[i+1].first){
m[i].first = k;
}
else{
m[i].first = k;
k++;
}
}
sort(m.begin(), m.end(), compara2);
for(int i=0; i<n; i++){
resp+= sum(m[i].first);
update(m[i].first,1);
}
cout << resp << endl;
return 0;
}