#include "kollib.h" #include "message.h" #include <iostream> #include <cstdlib> #include <unordered_set> #include <unordered_map> #include <vector> #include <utility> using namespace std; typedef pair<int,int> PII; PII go(int from, int dir, unordered_set<int>& special) { // cerr << "go(" << from << ", " << dir << ")" << endl; int dist = 1; while (special.find(dir) == special.end()) { dist++; int nei = FirstNeighbor(dir); if (nei == from) { nei = SecondNeighbor(dir); } from = dir; dir = nei; } return PII(dir, dist); } struct ListStruct { int first, firstDistance; int second, secondDistance; ListStruct(int f=0, int fd=0, int s=0, int sd=0) : first(f), firstDistance(fd), second(s), secondDistance(sd) {} }; int dist(int from, int to, unordered_map<int, ListStruct>& lst) { // cerr << "dist(" << from << ", " << to << ")" << endl; int res = 0; int prev = lst[from].first; while (from != to) { ListStruct vl = lst[from]; int nei = vl.first; int d = vl.firstDistance; if (prev == nei) { nei = vl.second; d = vl.secondDistance; } res += d; prev = from; from = nei; } return res; } int main() { srand(23); int N = NumberOfNodes(); int ID = MyNodeId(); int n = NumberOfStudents(); int q = NumberOfQueries(); unordered_set<int> special; vector<int> for_me; for (int i = 0; i < q; ++i) { int a = QueryFrom(i+1); int b = QueryTo(i+1); bool add = special.insert(a).second; if (add and i % N == ID) { for_me.push_back(a); } add = special.insert(b).second; if (add and i % N == ID) { for_me.push_back(b); } } int points = max(10 * N, min(5000, n / 100000)); //int points = 100; for (int i = 0; i < points; ++i) { int p = 1 + rand() % n; bool add = special.insert(p).second; if (i % N == ID and add) { for_me.push_back(p); } } PutInt(0, for_me.size()); for (int p : for_me) { PutInt(0, p); PII first = go(p, FirstNeighbor(p), special); PII second = go(p, SecondNeighbor(p), special); PutInt(0, first.first); PutInt(0, first.second); PutInt(0, second.first); PutInt(0, second.second); } Send(0); if (ID == 0) { unordered_map<int, ListStruct> lst; for (int i = 0; i < N; ++i) { int inst = Receive(-1); int m = GetInt(inst); for (int j = 0; j < m; ++j) { int p = GetInt(inst); int l, ld, r, rd; l = GetInt(inst); ld = GetInt(inst); r = GetInt(inst); rd = GetInt(inst); lst[p] = ListStruct(l, ld, r, rd); } } for (int i = 0; i < q; ++i) { int a = QueryFrom(i+1); int b = QueryTo(i+1); int d = dist(a, b, lst); printf("%d\n", min(d, n-d)); } } 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 | #include "kollib.h" #include "message.h" #include <iostream> #include <cstdlib> #include <unordered_set> #include <unordered_map> #include <vector> #include <utility> using namespace std; typedef pair<int,int> PII; PII go(int from, int dir, unordered_set<int>& special) { // cerr << "go(" << from << ", " << dir << ")" << endl; int dist = 1; while (special.find(dir) == special.end()) { dist++; int nei = FirstNeighbor(dir); if (nei == from) { nei = SecondNeighbor(dir); } from = dir; dir = nei; } return PII(dir, dist); } struct ListStruct { int first, firstDistance; int second, secondDistance; ListStruct(int f=0, int fd=0, int s=0, int sd=0) : first(f), firstDistance(fd), second(s), secondDistance(sd) {} }; int dist(int from, int to, unordered_map<int, ListStruct>& lst) { // cerr << "dist(" << from << ", " << to << ")" << endl; int res = 0; int prev = lst[from].first; while (from != to) { ListStruct vl = lst[from]; int nei = vl.first; int d = vl.firstDistance; if (prev == nei) { nei = vl.second; d = vl.secondDistance; } res += d; prev = from; from = nei; } return res; } int main() { srand(23); int N = NumberOfNodes(); int ID = MyNodeId(); int n = NumberOfStudents(); int q = NumberOfQueries(); unordered_set<int> special; vector<int> for_me; for (int i = 0; i < q; ++i) { int a = QueryFrom(i+1); int b = QueryTo(i+1); bool add = special.insert(a).second; if (add and i % N == ID) { for_me.push_back(a); } add = special.insert(b).second; if (add and i % N == ID) { for_me.push_back(b); } } int points = max(10 * N, min(5000, n / 100000)); //int points = 100; for (int i = 0; i < points; ++i) { int p = 1 + rand() % n; bool add = special.insert(p).second; if (i % N == ID and add) { for_me.push_back(p); } } PutInt(0, for_me.size()); for (int p : for_me) { PutInt(0, p); PII first = go(p, FirstNeighbor(p), special); PII second = go(p, SecondNeighbor(p), special); PutInt(0, first.first); PutInt(0, first.second); PutInt(0, second.first); PutInt(0, second.second); } Send(0); if (ID == 0) { unordered_map<int, ListStruct> lst; for (int i = 0; i < N; ++i) { int inst = Receive(-1); int m = GetInt(inst); for (int j = 0; j < m; ++j) { int p = GetInt(inst); int l, ld, r, rd; l = GetInt(inst); ld = GetInt(inst); r = GetInt(inst); rd = GetInt(inst); lst[p] = ListStruct(l, ld, r, rd); } } for (int i = 0; i < q; ++i) { int a = QueryFrom(i+1); int b = QueryTo(i+1); int d = dist(a, b, lst); printf("%d\n", min(d, n-d)); } } return 0; } |