#define LOCAL false #include <cstdio> #include <vector> #include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> #include <chrono> #include "message.h" #include "teatr.h" const int IntervalMax = 2e6; const int IntervalMin = IntervalMax / 4; const int N = 1e8; const int K = 1e6 + 69; const int RK = 1e6 + 2; int T[K]; struct Metadata { int Left = -1; int Right = -1; }; Metadata Meta[200]; void Init() { int nodes = NumberOfNodes(); long long sum = GetN(); long long perNode = std::max(1ll, sum/nodes); int last = 0; for (int i = 0; i < nodes-1 && sum > 0; i++) { Meta[i].Left = last; Meta[i].Right = last + perNode-1; last += perNode; sum -= perNode; } if (sum > 0) { Meta[nodes - 1].Left = last; Meta[nodes - 1].Right = last + sum-1; } } void BuildTree() { int j; for (int i = 1; i <= RK; i++) { j = i + (i&-i); if (j <= RK) T[j] += T[i]; } } void Insert(int x) { for (; x <= RK; x += (x&-x)) T[x]++; } int Query(int x) { int res = 0; for (; x > 0; x -= (x&-x)) res += T[x]; return res; } int main() { Init(); int left = Meta[MyNodeId()].Left; int right = Meta[MyNodeId()].Right; int n = GetN(); long long res = 0; if (left == -1 || right == -1) { goto END; } for (int i = n-1; i > right; i--) { T[GetElement(i)]++; } BuildTree(); int x; for (int i = right; i >= left; i--) { x = GetElement(i); Insert(x); res += Query(x-1); } END:; if (MyNodeId() == 0) { #if !LOCAL for (int i = 1; i < NumberOfNodes(); i++) { int recv = Receive(i); res += GetLL(recv); } #endif printf("%lld\n", res); } else { #if !LOCAL PutLL(0, res); Send(0); #endif } 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #define LOCAL false #include <cstdio> #include <vector> #include <cstdio> #include <iostream> #include <algorithm> #include <cstdlib> #include <chrono> #include "message.h" #include "teatr.h" const int IntervalMax = 2e6; const int IntervalMin = IntervalMax / 4; const int N = 1e8; const int K = 1e6 + 69; const int RK = 1e6 + 2; int T[K]; struct Metadata { int Left = -1; int Right = -1; }; Metadata Meta[200]; void Init() { int nodes = NumberOfNodes(); long long sum = GetN(); long long perNode = std::max(1ll, sum/nodes); int last = 0; for (int i = 0; i < nodes-1 && sum > 0; i++) { Meta[i].Left = last; Meta[i].Right = last + perNode-1; last += perNode; sum -= perNode; } if (sum > 0) { Meta[nodes - 1].Left = last; Meta[nodes - 1].Right = last + sum-1; } } void BuildTree() { int j; for (int i = 1; i <= RK; i++) { j = i + (i&-i); if (j <= RK) T[j] += T[i]; } } void Insert(int x) { for (; x <= RK; x += (x&-x)) T[x]++; } int Query(int x) { int res = 0; for (; x > 0; x -= (x&-x)) res += T[x]; return res; } int main() { Init(); int left = Meta[MyNodeId()].Left; int right = Meta[MyNodeId()].Right; int n = GetN(); long long res = 0; if (left == -1 || right == -1) { goto END; } for (int i = n-1; i > right; i--) { T[GetElement(i)]++; } BuildTree(); int x; for (int i = right; i >= left; i--) { x = GetElement(i); Insert(x); res += Query(x-1); } END:; if (MyNodeId() == 0) { #if !LOCAL for (int i = 1; i < NumberOfNodes(); i++) { int recv = Receive(i); res += GetLL(recv); } #endif printf("%lld\n", res); } else { #if !LOCAL PutLL(0, res); Send(0); #endif } return 0; } |