#include <cstdio> #include <vector> #include <queue> using namespace std; int top[100001]; vector<int> components; //struct conn_indexor { // int comp_start; // int elements; // // conn_indexor(int comp_start, int elements) { // this->comp_start = comp_start; // this->elements = elements; // } // // int conn_idx(int a_idx, int b_idx) { // int true_a_idx = a_idx - comp_start; // int true_b_idx = b_idx - comp_start; // return (true_a_idx * elements + b_idx); // } //}; struct tovisit { int index; int path; tovisit(int index, int path) { this->index = index; this->path = path; } }; void calc_and_out(int component_start, int component_end) { // printf("COMPONENT: %d..%d\n", component_start, component_end); // n^2 - do it better for some real points... int elements = component_end - component_start + 1; if (elements == 1) { printf("0 "); return; } // int connections = elements * elements; bool *visited = new bool[elements]; vector<int> *neighs = new vector<int>[elements]; // int *neighmatrix = new int[connections]; // conn_indexor dexor = conn_indexor(component_start, elements); for (int i = component_start; i <= component_end; ++i) { vector<int> pty; neighs[i-component_start] = pty; } for (int i = component_start; i <= component_end; ++i) { // create edges for (int j = i+1; j <= component_end; ++j) { // printf("%d->%d, %d->%d\n", i, top[i], j, top[j]); if (top[j] < top[i]) { // printf("Collision!\n"); neighs[i-component_start].push_back(j-component_start); neighs[j-component_start].push_back(i-component_start); } } } // printf("NEW COMPONENT CONNECTIONS:\n"); // for (int i = component_start; i <= component_end; ++i) { // printf("%d: ", i-component_start); // for (int j: neighs[i-component_start]) { // printf("%d ", j); // } // printf("\n"); // } for (int i = component_start; i <= component_end; ++i) { for (int j = component_start; j <= component_end; ++j) { visited[j-component_start] = false; } int totalpath = 0; queue<tovisit> q; tovisit startingpoint(i-component_start, 0); q.push(startingpoint); visited[i-component_start] = true; while (!q.empty()) { int next_dest = q.front().index; int thispath = q.front().path; totalpath += thispath; q.pop(); for (int j: neighs[next_dest]) { if (!visited[j]) { visited[j] = true; tovisit nextpoint(j, thispath+1); q.push(nextpoint); } } } printf("%d ", totalpath); // compute all paths from i } delete [] visited; delete [] neighs; } int main() { int n; scanf("%d", &n); int component_start = 1; int component_end = 0; long long sumi = 0; long long sumscanned = 0; for (int i = 1; i <= n; ++i) { scanf("%d", &top[i]); sumi += i; sumscanned += top[i]; if (sumi == sumscanned) { component_end = i; components.push_back(i); calc_and_out(component_start, component_end); component_start = i+1; } } printf("\n"); 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 | #include <cstdio> #include <vector> #include <queue> using namespace std; int top[100001]; vector<int> components; //struct conn_indexor { // int comp_start; // int elements; // // conn_indexor(int comp_start, int elements) { // this->comp_start = comp_start; // this->elements = elements; // } // // int conn_idx(int a_idx, int b_idx) { // int true_a_idx = a_idx - comp_start; // int true_b_idx = b_idx - comp_start; // return (true_a_idx * elements + b_idx); // } //}; struct tovisit { int index; int path; tovisit(int index, int path) { this->index = index; this->path = path; } }; void calc_and_out(int component_start, int component_end) { // printf("COMPONENT: %d..%d\n", component_start, component_end); // n^2 - do it better for some real points... int elements = component_end - component_start + 1; if (elements == 1) { printf("0 "); return; } // int connections = elements * elements; bool *visited = new bool[elements]; vector<int> *neighs = new vector<int>[elements]; // int *neighmatrix = new int[connections]; // conn_indexor dexor = conn_indexor(component_start, elements); for (int i = component_start; i <= component_end; ++i) { vector<int> pty; neighs[i-component_start] = pty; } for (int i = component_start; i <= component_end; ++i) { // create edges for (int j = i+1; j <= component_end; ++j) { // printf("%d->%d, %d->%d\n", i, top[i], j, top[j]); if (top[j] < top[i]) { // printf("Collision!\n"); neighs[i-component_start].push_back(j-component_start); neighs[j-component_start].push_back(i-component_start); } } } // printf("NEW COMPONENT CONNECTIONS:\n"); // for (int i = component_start; i <= component_end; ++i) { // printf("%d: ", i-component_start); // for (int j: neighs[i-component_start]) { // printf("%d ", j); // } // printf("\n"); // } for (int i = component_start; i <= component_end; ++i) { for (int j = component_start; j <= component_end; ++j) { visited[j-component_start] = false; } int totalpath = 0; queue<tovisit> q; tovisit startingpoint(i-component_start, 0); q.push(startingpoint); visited[i-component_start] = true; while (!q.empty()) { int next_dest = q.front().index; int thispath = q.front().path; totalpath += thispath; q.pop(); for (int j: neighs[next_dest]) { if (!visited[j]) { visited[j] = true; tovisit nextpoint(j, thispath+1); q.push(nextpoint); } } } printf("%d ", totalpath); // compute all paths from i } delete [] visited; delete [] neighs; } int main() { int n; scanf("%d", &n); int component_start = 1; int component_end = 0; long long sumi = 0; long long sumscanned = 0; for (int i = 1; i <= n; ++i) { scanf("%d", &top[i]); sumi += i; sumscanned += top[i]; if (sumi == sumscanned) { component_end = i; components.push_back(i); calc_and_out(component_start, component_end); component_start = i+1; } } printf("\n"); return 0; } |