#include<cstdio> #include "message.h" #include "teatr.h" int M = 1000000; int start; int end; int number_of_nodes; int node_id; int * t; int * counts; int * prev_counts; int * tmp; int biggest = 0; int prev_biggest = 0; long long local_result = 0; int min(int a, int b) { return a > b ? b : a; } int max(int a, int b) { return a > b ? a : b; } void init() { node_id = MyNodeId(); number_of_nodes = NumberOfNodes(); int n = GetN(); start = min(node_id * M, n); end = min((node_id + 1) * M, n); counts = new int[M + 5]; prev_counts = new int[M + 5]; t = new int[M + 5]; tmp = new int[M + 5]; for (int i = 0; i < M + 5; i++) { counts[i] = 0; prev_counts[i] = 0; } for (int i = start; i < end; i++) { t[i - start] = GetElement(i); } } long long merge(int left, int mid, int right) { long long inversions = 0; int i = left; int j = mid; int k = left; while((i <= mid - 1) && (j <= right)) { if (t[i] <= t[j]) { tmp[k++] = t[i++]; } else { tmp[k++] = t[j++]; inversions += (mid - i); } } while(i <= mid - 1) { tmp[k++] = t[i++]; } while(j <= right) { tmp[k++] = t[j++]; } for (int i = left; i <= right; i++) { t[i] = tmp[i]; } return inversions; } long long merge_sort(int left, int right) { int mid; long long inversions = 0; if (right > left) { mid = (right + left) / 2; inversions += merge_sort(left, mid); inversions += merge_sort(mid + 1, right); inversions += merge(left, mid + 1, right); } return inversions; } long long count_inversions() { if (end == start) { return 0; } return merge_sort(0, end - start - 1); } void compute_local() { local_result = count_inversions(); } void count() { for (int i = start; i < end; i++) { int next = t[i - start]; counts[next]++; biggest = max(biggest, next); } } void receive_counts() { if (node_id != 0) { Receive(node_id - 1); prev_biggest = GetInt(node_id - 1); for (int i = 0; i < prev_biggest; i++) { prev_counts[i] = GetInt(node_id - 1); } biggest = max(biggest, prev_biggest); } } void send_counts() { if (node_id != number_of_nodes - 1) { PutInt(node_id + 1, biggest + 1); for (int i = 0; i <= biggest; i++) { PutInt(node_id + 1, counts[i] + prev_counts[i]); } Send(node_id + 1); } } void update_result_with_counts() { for (int i = prev_biggest; i >= 0; i--) { prev_counts[i] += prev_counts[i + 1]; } for (int i = start; i < end; i++) { int next = t[i - start]; local_result += prev_counts[next + 1]; } //printf("%d %d %lld\n", prev_counts[0], prev_counts[1], local_result); } void receive_result() { if (node_id != 0) { Receive(node_id - 1); local_result += GetLL(node_id - 1); } } void forward_result() { if (node_id != number_of_nodes - 1) { PutLL(node_id + 1, local_result); Send(node_id + 1); } else { printf("%lld\n", local_result); } } int main() { init(); compute_local(); count(); receive_counts(); send_counts(); update_result_with_counts(); receive_result(); forward_result(); 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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #include<cstdio> #include "message.h" #include "teatr.h" int M = 1000000; int start; int end; int number_of_nodes; int node_id; int * t; int * counts; int * prev_counts; int * tmp; int biggest = 0; int prev_biggest = 0; long long local_result = 0; int min(int a, int b) { return a > b ? b : a; } int max(int a, int b) { return a > b ? a : b; } void init() { node_id = MyNodeId(); number_of_nodes = NumberOfNodes(); int n = GetN(); start = min(node_id * M, n); end = min((node_id + 1) * M, n); counts = new int[M + 5]; prev_counts = new int[M + 5]; t = new int[M + 5]; tmp = new int[M + 5]; for (int i = 0; i < M + 5; i++) { counts[i] = 0; prev_counts[i] = 0; } for (int i = start; i < end; i++) { t[i - start] = GetElement(i); } } long long merge(int left, int mid, int right) { long long inversions = 0; int i = left; int j = mid; int k = left; while((i <= mid - 1) && (j <= right)) { if (t[i] <= t[j]) { tmp[k++] = t[i++]; } else { tmp[k++] = t[j++]; inversions += (mid - i); } } while(i <= mid - 1) { tmp[k++] = t[i++]; } while(j <= right) { tmp[k++] = t[j++]; } for (int i = left; i <= right; i++) { t[i] = tmp[i]; } return inversions; } long long merge_sort(int left, int right) { int mid; long long inversions = 0; if (right > left) { mid = (right + left) / 2; inversions += merge_sort(left, mid); inversions += merge_sort(mid + 1, right); inversions += merge(left, mid + 1, right); } return inversions; } long long count_inversions() { if (end == start) { return 0; } return merge_sort(0, end - start - 1); } void compute_local() { local_result = count_inversions(); } void count() { for (int i = start; i < end; i++) { int next = t[i - start]; counts[next]++; biggest = max(biggest, next); } } void receive_counts() { if (node_id != 0) { Receive(node_id - 1); prev_biggest = GetInt(node_id - 1); for (int i = 0; i < prev_biggest; i++) { prev_counts[i] = GetInt(node_id - 1); } biggest = max(biggest, prev_biggest); } } void send_counts() { if (node_id != number_of_nodes - 1) { PutInt(node_id + 1, biggest + 1); for (int i = 0; i <= biggest; i++) { PutInt(node_id + 1, counts[i] + prev_counts[i]); } Send(node_id + 1); } } void update_result_with_counts() { for (int i = prev_biggest; i >= 0; i--) { prev_counts[i] += prev_counts[i + 1]; } for (int i = start; i < end; i++) { int next = t[i - start]; local_result += prev_counts[next + 1]; } //printf("%d %d %lld\n", prev_counts[0], prev_counts[1], local_result); } void receive_result() { if (node_id != 0) { Receive(node_id - 1); local_result += GetLL(node_id - 1); } } void forward_result() { if (node_id != number_of_nodes - 1) { PutLL(node_id + 1, local_result); Send(node_id + 1); } else { printf("%lld\n", local_result); } } int main() { init(); compute_local(); count(); receive_counts(); send_counts(); update_result_with_counts(); receive_result(); forward_result(); return 0; } |