#include "message.h" #include "krazki.h" #include <cstdio> #include <algorithm> using namespace std; #define MAXN 1000007 int n, m, current_batch, local_height; long long kra[MAXN]; long long minima[207]; const int batch_size = 1000000; int batches; void read_batch(int id) { int start = id * batch_size; int ind = start; while(ind < n && ind < (id + 1) * batch_size) { int i = ind - start; kra[i] = HoleDiameter(1 + ind); if (i) { kra[i] = std::min(kra[i], kra[i-1]); } else if (id) { kra[i] = std::min(kra[i], minima[id-1]); } ind++; } } bool decrease_height() { if (local_height == 0) { //next batch if (current_batch == 0) { printf("0\n"); return false; } current_batch--; read_batch(current_batch); local_height = batch_size; } else { local_height--; } return true; } bool process_next_disc(int id) { long long disc = DiscDiameter(id + 1); // printf("local height: %d, kra %lld\n", local_height, kra[local_height]); if (!decrease_height()) return false; while(disc > kra[local_height]) { if (!decrease_height()) return false; } // printf("finished\n"); return true; } int main() { if (MyNodeId() != 0) return 0; n = PipeHeight(); m = NumberOfDiscs(); batches = (n + batch_size - 1)/ batch_size; //get minimal sizes of each batch of 10**6 size minima[0] = 1000000000LL * 1000000000LL + 1LL; for (int i = 0; i * batch_size < n; i++) { if (i) minima[i] = minima[i-1]; for (int j = 0; j < batch_size; j++) { if (j + i * batch_size >= n) break; minima[i] = std::min(minima[i], HoleDiameter(1 + j + i * batch_size)); } } current_batch = batches; if (n % batch_size == 0) local_height = batch_size; else local_height = n % batch_size; read_batch(current_batch); for(int i = 0; i < m; i++) { if (!process_next_disc(i)) return 0; } printf("%d\n", local_height + 1 + current_batch * batch_size); }
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 | #include "message.h" #include "krazki.h" #include <cstdio> #include <algorithm> using namespace std; #define MAXN 1000007 int n, m, current_batch, local_height; long long kra[MAXN]; long long minima[207]; const int batch_size = 1000000; int batches; void read_batch(int id) { int start = id * batch_size; int ind = start; while(ind < n && ind < (id + 1) * batch_size) { int i = ind - start; kra[i] = HoleDiameter(1 + ind); if (i) { kra[i] = std::min(kra[i], kra[i-1]); } else if (id) { kra[i] = std::min(kra[i], minima[id-1]); } ind++; } } bool decrease_height() { if (local_height == 0) { //next batch if (current_batch == 0) { printf("0\n"); return false; } current_batch--; read_batch(current_batch); local_height = batch_size; } else { local_height--; } return true; } bool process_next_disc(int id) { long long disc = DiscDiameter(id + 1); // printf("local height: %d, kra %lld\n", local_height, kra[local_height]); if (!decrease_height()) return false; while(disc > kra[local_height]) { if (!decrease_height()) return false; } // printf("finished\n"); return true; } int main() { if (MyNodeId() != 0) return 0; n = PipeHeight(); m = NumberOfDiscs(); batches = (n + batch_size - 1)/ batch_size; //get minimal sizes of each batch of 10**6 size minima[0] = 1000000000LL * 1000000000LL + 1LL; for (int i = 0; i * batch_size < n; i++) { if (i) minima[i] = minima[i-1]; for (int j = 0; j < batch_size; j++) { if (j + i * batch_size >= n) break; minima[i] = std::min(minima[i], HoleDiameter(1 + j + i * batch_size)); } } current_batch = batches; if (n % batch_size == 0) local_height = batch_size; else local_height = n % batch_size; read_batch(current_batch); for(int i = 0; i < m; i++) { if (!process_next_disc(i)) return 0; } printf("%d\n", local_height + 1 + current_batch * batch_size); } |