#include "message.h" #include "teatr.h" #include "bits/stdc++.h" #include <cmath> #include <cassert> using namespace std; typedef long long ll; ll MAX_HEIGHT = 5; // Finds the inversions number [beg, end] with assumption that the max height equals 5 and counts the sizes ll countInvAndHeights(ll beg, ll end, vector<ll>& H) { fill(H.begin(), H.end(), 0); ll inv = 0; for (ll i = beg; i <= end; ++i) { ll h = GetElement(i); for (ll j = h; j < MAX_HEIGHT; ++j) { inv += H[j]; } H[h - 1] += 1; } return inv; } ll countInvBasedOnHalfs(vector<ll>& l, vector<ll>& r) { ll inv = 0; for (ll i = 0; i < MAX_HEIGHT; ++i) { for (ll j = i + 1; j < MAX_HEIGHT; ++j) { inv += r[i] * l[j]; } } return inv; } // Adds right to left vector. void addHalfs(vector<ll>& l, vector<ll>& r) { for (ll i = 0; i < MAX_HEIGHT; ++i) { l[i] += r[i]; } } int main() { ll id = MyNodeId(); ll nodesNo = NumberOfNodes(); ll n = GetN(); if (id >= n) { return 0; } nodesNo = min(nodesNo, n); vector<ll> H(MAX_HEIGHT); ll len = (n + nodesNo - 1) / nodesNo; ll beg = id * len; ll end = min(beg + len - 1, n - 1); //cout << "My starting block is [" << beg << ", " << end << "]" << endl; ll inv = countInvAndHeights(beg, end, H); //cout << "inv number in my starting block: " << inv << endl; ll round = 2; while (id % round == 0 && round / 2 <= nodesNo) { // Get id of your brother ll brotherId = id + (round / 2); // If you have brother, then receive message from him if (brotherId < nodesNo) { ll sender = Receive(brotherId); vector<ll> HB(MAX_HEIGHT); for (ll i = 0; i < MAX_HEIGHT; ++i) { HB[i] = GetInt(brotherId); } inv += GetInt(brotherId); inv += countInvBasedOnHalfs(H, HB); addHalfs(H, HB); } round *= 2; } // I'm the boss if (id == 0) { cout << inv << endl; return 0; } // if i'm not the boss, send my results to the guy on the left ll brotherId = id - (round / 2); for (ll i = 0; i < MAX_HEIGHT; ++i) { PutInt(brotherId, H[i]); } PutInt(brotherId, inv); Send(brotherId); return 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 | #include "message.h" #include "teatr.h" #include "bits/stdc++.h" #include <cmath> #include <cassert> using namespace std; typedef long long ll; ll MAX_HEIGHT = 5; // Finds the inversions number [beg, end] with assumption that the max height equals 5 and counts the sizes ll countInvAndHeights(ll beg, ll end, vector<ll>& H) { fill(H.begin(), H.end(), 0); ll inv = 0; for (ll i = beg; i <= end; ++i) { ll h = GetElement(i); for (ll j = h; j < MAX_HEIGHT; ++j) { inv += H[j]; } H[h - 1] += 1; } return inv; } ll countInvBasedOnHalfs(vector<ll>& l, vector<ll>& r) { ll inv = 0; for (ll i = 0; i < MAX_HEIGHT; ++i) { for (ll j = i + 1; j < MAX_HEIGHT; ++j) { inv += r[i] * l[j]; } } return inv; } // Adds right to left vector. void addHalfs(vector<ll>& l, vector<ll>& r) { for (ll i = 0; i < MAX_HEIGHT; ++i) { l[i] += r[i]; } } int main() { ll id = MyNodeId(); ll nodesNo = NumberOfNodes(); ll n = GetN(); if (id >= n) { return 0; } nodesNo = min(nodesNo, n); vector<ll> H(MAX_HEIGHT); ll len = (n + nodesNo - 1) / nodesNo; ll beg = id * len; ll end = min(beg + len - 1, n - 1); //cout << "My starting block is [" << beg << ", " << end << "]" << endl; ll inv = countInvAndHeights(beg, end, H); //cout << "inv number in my starting block: " << inv << endl; ll round = 2; while (id % round == 0 && round / 2 <= nodesNo) { // Get id of your brother ll brotherId = id + (round / 2); // If you have brother, then receive message from him if (brotherId < nodesNo) { ll sender = Receive(brotherId); vector<ll> HB(MAX_HEIGHT); for (ll i = 0; i < MAX_HEIGHT; ++i) { HB[i] = GetInt(brotherId); } inv += GetInt(brotherId); inv += countInvBasedOnHalfs(H, HB); addHalfs(H, HB); } round *= 2; } // I'm the boss if (id == 0) { cout << inv << endl; return 0; } // if i'm not the boss, send my results to the guy on the left ll brotherId = id - (round / 2); for (ll i = 0; i < MAX_HEIGHT; ++i) { PutInt(brotherId, H[i]); } PutInt(brotherId, inv); Send(brotherId); return 0; } |