#include <cstdio> #include <cstdlib> #include <message.h> #include <climits> #include <algorithm> #include "kollib.h" #include <set> #include <map> #include <vector> int Q[400]; std::set<int> SX; int X[100000]; int V[100000]; int D[100000]; std::multimap<int, std::pair<int, int> > Map; std::map<int, int> Pos; unsigned short lfsr = 0xACE1u; // Just for sure unsigned my_rand() { unsigned register bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1; return lfsr = (lfsr >> 1) | (bit << 15); } int main() { int I = MyNodeId(), M = NumberOfNodes(); int N = NumberOfStudents(); int K = NumberOfQueries(); if( M%2 == 0 ) M--; M--; if( I > M ) { //puts("I am useless. :-("); return 0; } if( I == M ) { //puts("I am server. :-)"); } for( int i = 1; i <= K; i++ ) { SX.insert(QueryFrom(i)); SX.insert(QueryTo(i)); } for( int i = 0; i < M*400; i++ ) { SX.insert( ( 1LL*my_rand()*RAND_MAX + my_rand() ) % N + 1 ); } int LX = 0; for( std::set<int>::iterator it = SX.begin(); it != SX.end() and 2*LX/M < 960; it++ ) { X[LX++] = *it; } if( I < M ) for( int i = I/2; i < LX; i += M/2 ) { int from = X[i]; int previous = from; int x = (I%2 == 0) ? FirstNeighbor(from) : SecondNeighbor(from); int distance = 1; while( SX.count(x) == 0 ) { int y = FirstNeighbor(x); if( y == previous ) y = SecondNeighbor(x); previous = x; x = y; distance++; } //printf("calculated[%d] %d->%d\n", i, from, x ); PutInt(M, from); PutInt(M, x); PutInt(M, distance); Send(M); //puts("sending"); } if( I == M ) { int n = 1; V[0] = X[0]; D[0] = 0; int total = LX; while( n < total ) { int i = Receive(-1); int a = GetInt(i), b = GetInt(i); int dist = GetInt(i); //printf("recieving(%d): %d %d %d\n", i, a, b, dist ); Map.insert( std::make_pair( a, std::make_pair(b, dist) ) ); Map.insert( std::make_pair( b, std::make_pair(a, dist) ) ); while( n < total and Map.count(V[n-1]) > 0 ) { a = V[n-1]; std::multimap<int, std::pair<int, int> >::iterator it = Map.find(a); b = it->second.first; dist = it->second.second; if( n == 1 or V[n-2] != b ) { //printf("Adding %d after %d\n", b, a ); V[n] = b; D[n] = D[n-1]+dist; n++; } Map.erase(it); } } for( int i = 0; i < total; i++ ) { Pos[V[i]] = D[i]; } for( int i = 1; i <= K; i++ ) { int a = QueryFrom(i), b = QueryTo(i); int d = (Pos[a] - Pos[b] + N)%N; d = std::min(d, N-d); printf("%d\n", d); } } }
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 | #include <cstdio> #include <cstdlib> #include <message.h> #include <climits> #include <algorithm> #include "kollib.h" #include <set> #include <map> #include <vector> int Q[400]; std::set<int> SX; int X[100000]; int V[100000]; int D[100000]; std::multimap<int, std::pair<int, int> > Map; std::map<int, int> Pos; unsigned short lfsr = 0xACE1u; // Just for sure unsigned my_rand() { unsigned register bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1; return lfsr = (lfsr >> 1) | (bit << 15); } int main() { int I = MyNodeId(), M = NumberOfNodes(); int N = NumberOfStudents(); int K = NumberOfQueries(); if( M%2 == 0 ) M--; M--; if( I > M ) { //puts("I am useless. :-("); return 0; } if( I == M ) { //puts("I am server. :-)"); } for( int i = 1; i <= K; i++ ) { SX.insert(QueryFrom(i)); SX.insert(QueryTo(i)); } for( int i = 0; i < M*400; i++ ) { SX.insert( ( 1LL*my_rand()*RAND_MAX + my_rand() ) % N + 1 ); } int LX = 0; for( std::set<int>::iterator it = SX.begin(); it != SX.end() and 2*LX/M < 960; it++ ) { X[LX++] = *it; } if( I < M ) for( int i = I/2; i < LX; i += M/2 ) { int from = X[i]; int previous = from; int x = (I%2 == 0) ? FirstNeighbor(from) : SecondNeighbor(from); int distance = 1; while( SX.count(x) == 0 ) { int y = FirstNeighbor(x); if( y == previous ) y = SecondNeighbor(x); previous = x; x = y; distance++; } //printf("calculated[%d] %d->%d\n", i, from, x ); PutInt(M, from); PutInt(M, x); PutInt(M, distance); Send(M); //puts("sending"); } if( I == M ) { int n = 1; V[0] = X[0]; D[0] = 0; int total = LX; while( n < total ) { int i = Receive(-1); int a = GetInt(i), b = GetInt(i); int dist = GetInt(i); //printf("recieving(%d): %d %d %d\n", i, a, b, dist ); Map.insert( std::make_pair( a, std::make_pair(b, dist) ) ); Map.insert( std::make_pair( b, std::make_pair(a, dist) ) ); while( n < total and Map.count(V[n-1]) > 0 ) { a = V[n-1]; std::multimap<int, std::pair<int, int> >::iterator it = Map.find(a); b = it->second.first; dist = it->second.second; if( n == 1 or V[n-2] != b ) { //printf("Adding %d after %d\n", b, a ); V[n] = b; D[n] = D[n-1]+dist; n++; } Map.erase(it); } } for( int i = 0; i < total; i++ ) { Pos[V[i]] = D[i]; } for( int i = 1; i <= K; i++ ) { int a = QueryFrom(i), b = QueryTo(i); int d = (Pos[a] - Pos[b] + N)%N; d = std::min(d, N-d); printf("%d\n", d); } } } |