#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; } |
English