#include "message.h"
#include <bits/stdc++.h>
#include "teatr.h"
using namespace std;
const int N = 1000 * 1000 + 10;
const int MAXN = 1000 * 1000;
const int rozmiar = 1 << 20;
int war_pop[N];
int war_akt[N];
int d_p[2 * rozmiar];
void dodaj(int v) {
v += rozmiar;
while (v > 0) {
d_p[v]++;
v /= 2;
}
}
long long suma (int pocz, int kon) {
pocz += rozmiar;
kon += rozmiar;
long long wynik = d_p[pocz];
if (pocz != kon)
wynik += d_p[kon];
while (pocz / 2 != kon / 2) {
if (pocz % 2 == 0)
wynik += d_p[pocz + 1];
if (kon % 2 == 1)
wynik += d_p[kon - 1];
pocz /= 2;
kon /= 2;
}
return wynik;
}
long long count_inversion(int pocz, int kon) {
long long wynik = 0;
int wzrost;
for (int i = pocz; i <= kon; i++) {
wzrost = GetElement(i);
wynik += suma(wzrost + 1, rozmiar - 1);
dodaj(wzrost);
}
return wynik;
}
int main() {
int n = GetN(), node_id = MyNodeId(), instance_number = NumberOfNodes();
long long wynik = 0;
if (n <= 200) {
if (node_id == 0)
cout << count_inversion(0, n -1);
return 0;
}
if (node_id == 0) {
int przedzial = n / instance_number;
for (int i = 0; i < n; i++) {
war_akt[GetElement(i)]++;
if ((i + 1) % przedzial == 0 && i < (instance_number - 2) * przedzial) {
//cout << i << "\n";
long long suma_przed = 0;
for (int j = 1; j <= MAXN; j++) {
wynik += (long long)war_akt[MAXN - j + 1] * suma_przed;
suma_przed += (long long)war_pop[MAXN - j + 1];
}
for (int j = 0; j < N; j++) {
war_pop[j] += war_akt[j];
war_akt[j] = 0;
}
}
}
long long suma_przed = 0;
for (int j = 1; j <= MAXN; j++) {
wynik += (long long)war_akt[MAXN - j + 1] * suma_przed;
suma_przed += (long long)war_pop[MAXN - j + 1];
}
for (int i = 1; i < instance_number; i++) {
Receive(i);
wynik += GetLL(i);
}
cout << wynik << "\n";
} else {
int przedzial = n / instance_number;
int pocz = (node_id - 1) * przedzial;
int kon = (node_id - 1) * przedzial + przedzial - 1;
if (node_id == instance_number - 1)
kon = n - 1;
//cout << przedzial << " " << pocz << " " << kon << "\n";
PutLL(0, count_inversion(pocz, kon));
Send(0);
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | #include "message.h" #include <bits/stdc++.h> #include "teatr.h" using namespace std; const int N = 1000 * 1000 + 10; const int MAXN = 1000 * 1000; const int rozmiar = 1 << 20; int war_pop[N]; int war_akt[N]; int d_p[2 * rozmiar]; void dodaj(int v) { v += rozmiar; while (v > 0) { d_p[v]++; v /= 2; } } long long suma (int pocz, int kon) { pocz += rozmiar; kon += rozmiar; long long wynik = d_p[pocz]; if (pocz != kon) wynik += d_p[kon]; while (pocz / 2 != kon / 2) { if (pocz % 2 == 0) wynik += d_p[pocz + 1]; if (kon % 2 == 1) wynik += d_p[kon - 1]; pocz /= 2; kon /= 2; } return wynik; } long long count_inversion(int pocz, int kon) { long long wynik = 0; int wzrost; for (int i = pocz; i <= kon; i++) { wzrost = GetElement(i); wynik += suma(wzrost + 1, rozmiar - 1); dodaj(wzrost); } return wynik; } int main() { int n = GetN(), node_id = MyNodeId(), instance_number = NumberOfNodes(); long long wynik = 0; if (n <= 200) { if (node_id == 0) cout << count_inversion(0, n -1); return 0; } if (node_id == 0) { int przedzial = n / instance_number; for (int i = 0; i < n; i++) { war_akt[GetElement(i)]++; if ((i + 1) % przedzial == 0 && i < (instance_number - 2) * przedzial) { //cout << i << "\n"; long long suma_przed = 0; for (int j = 1; j <= MAXN; j++) { wynik += (long long)war_akt[MAXN - j + 1] * suma_przed; suma_przed += (long long)war_pop[MAXN - j + 1]; } for (int j = 0; j < N; j++) { war_pop[j] += war_akt[j]; war_akt[j] = 0; } } } long long suma_przed = 0; for (int j = 1; j <= MAXN; j++) { wynik += (long long)war_akt[MAXN - j + 1] * suma_przed; suma_przed += (long long)war_pop[MAXN - j + 1]; } for (int i = 1; i < instance_number; i++) { Receive(i); wynik += GetLL(i); } cout << wynik << "\n"; } else { int przedzial = n / instance_number; int pocz = (node_id - 1) * przedzial; int kon = (node_id - 1) * przedzial + przedzial - 1; if (node_id == instance_number - 1) kon = n - 1; //cout << przedzial << " " << pocz << " " << kon << "\n"; PutLL(0, count_inversion(pocz, kon)); Send(0); } } |
English