#include "message.h"
#include "teatr.h"
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for (int i = (a); i <= (b); ++i)
#define REPD(i,a,b) for (int i = (a); i >= (b); --i)
#define FORI(i,n) REP(i,1,n)
#define FOR(i,n) REP(i,0,int(n)-1)
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define ll long long
#define SZ(x) int((x).size())
#define DBG(v) cerr << #v << " = " << (v) << endl;
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define fi first
#define se second
const int K = 14; // todo 14
const int N = 8000000;
int my_id, nodes, n;
int a[N], b[N];
ll get(int le, int ri) {
if (le+1 >= ri) return 0;
int mi = (le+ri) / 2;
ll res = get(le, mi) + get(mi, ri);
//printf("get %d %d -> %lld\n", le, ri, res);
//for (int i = le; i < ri; i++) printf("%d ", a[i]); printf("\n");
int i=le, j=mi, k=0;
while (i < mi && j < ri) {
if (a[i] <= a[j]) {
b[k++] = a[i++];
} else {
res += mi-i;
b[k++] = a[j++];
}
}
while (i<mi) {
b[k++] = a[i++];
}
while (j<ri) {
b[k++] = a[j++];
}
for (int i = le; i < ri; i++) a[i] = b[i-le];
//printf("get %d %d -> %lld\n", le, ri, res);
return res;
}
ll one_seg(int seg_id) {
int l = 1LL * seg_id * n / K, r = 1LL * (seg_id+1) * n / K;
for (int i = l; i < r; i++) a[i-l] = GetElement(i);
int m = r-l;
ll res = get(0, m);
//printf("segment %d (%d %d): %lld\n", seg_id, l, r, res);
return res;
}
ll two_segs(int seg_a, int seg_b) {
int al = 1LL * seg_a * n / K, ar = 1LL * (seg_a+1) * n / K;
int bl = 1LL * seg_b * n / K, br = 1LL * (seg_b+1) * n / K;
for (int i = al; i < ar; i++) a[i-al] = GetElement(i);
for (int i = bl; i < br; i++) b[i-bl] = GetElement(i);
int an = ar-al, bn = br-bl;
sort(a,a+an);
sort(b,b+bn);
ll res = 0;
int j = 0;
FOR(i,an) {
while (j<bn && b[j]<a[i]) j++;
res += j;
}
//printf("segments %d %d : %lld\n", seg_a, seg_b, res);
return res;
}
int main() {
my_id = MyNodeId();
nodes = NumberOfNodes();
n = GetN();
int M = (K*K-K)/2;
ll my_inv = 0;
if (my_id < M) { // robimy pary przedzialow
int seg_le, seg_ri, q=0;
for (int i = 0; i < K; i++) for (int j = 0; j < i; j++) {
if (my_id == q) {
seg_ri = i;
seg_le = j;
}
q++;
}
my_inv = two_segs(seg_le, seg_ri);
} else { // robimy wewnatrz przedzialow
int rem = nodes - M;
for (int i = 0; i < K; i++) if (i%rem == my_id-M) {
my_inv += one_seg(i);
}
}
PutLL(0, my_inv);
Send(0);
if (my_id == 0) {
ll res = 0;
FOR(i,nodes) {
Receive(i);
long long tmp = GetLL(i);
res += tmp;
}
printf("%lld\n", res);
}
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 | #include "message.h" #include "teatr.h" #include <bits/stdc++.h> using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define REPD(i,a,b) for (int i = (a); i >= (b); --i) #define FORI(i,n) REP(i,1,n) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair<int,int> #define vi vector<int> #define ll long long #define SZ(x) int((x).size()) #define DBG(v) cerr << #v << " = " << (v) << endl; #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define fi first #define se second const int K = 14; // todo 14 const int N = 8000000; int my_id, nodes, n; int a[N], b[N]; ll get(int le, int ri) { if (le+1 >= ri) return 0; int mi = (le+ri) / 2; ll res = get(le, mi) + get(mi, ri); //printf("get %d %d -> %lld\n", le, ri, res); //for (int i = le; i < ri; i++) printf("%d ", a[i]); printf("\n"); int i=le, j=mi, k=0; while (i < mi && j < ri) { if (a[i] <= a[j]) { b[k++] = a[i++]; } else { res += mi-i; b[k++] = a[j++]; } } while (i<mi) { b[k++] = a[i++]; } while (j<ri) { b[k++] = a[j++]; } for (int i = le; i < ri; i++) a[i] = b[i-le]; //printf("get %d %d -> %lld\n", le, ri, res); return res; } ll one_seg(int seg_id) { int l = 1LL * seg_id * n / K, r = 1LL * (seg_id+1) * n / K; for (int i = l; i < r; i++) a[i-l] = GetElement(i); int m = r-l; ll res = get(0, m); //printf("segment %d (%d %d): %lld\n", seg_id, l, r, res); return res; } ll two_segs(int seg_a, int seg_b) { int al = 1LL * seg_a * n / K, ar = 1LL * (seg_a+1) * n / K; int bl = 1LL * seg_b * n / K, br = 1LL * (seg_b+1) * n / K; for (int i = al; i < ar; i++) a[i-al] = GetElement(i); for (int i = bl; i < br; i++) b[i-bl] = GetElement(i); int an = ar-al, bn = br-bl; sort(a,a+an); sort(b,b+bn); ll res = 0; int j = 0; FOR(i,an) { while (j<bn && b[j]<a[i]) j++; res += j; } //printf("segments %d %d : %lld\n", seg_a, seg_b, res); return res; } int main() { my_id = MyNodeId(); nodes = NumberOfNodes(); n = GetN(); int M = (K*K-K)/2; ll my_inv = 0; if (my_id < M) { // robimy pary przedzialow int seg_le, seg_ri, q=0; for (int i = 0; i < K; i++) for (int j = 0; j < i; j++) { if (my_id == q) { seg_ri = i; seg_le = j; } q++; } my_inv = two_segs(seg_le, seg_ri); } else { // robimy wewnatrz przedzialow int rem = nodes - M; for (int i = 0; i < K; i++) if (i%rem == my_id-M) { my_inv += one_seg(i); } } PutLL(0, my_inv); Send(0); if (my_id == 0) { ll res = 0; FOR(i,nodes) { Receive(i); long long tmp = GetLL(i); res += tmp; } printf("%lld\n", res); } return 0; } |
English