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