#include <cstdio>
#include "kollib.h"
#include "message.h"
using namespace std;
struct node {
int time;
bool isPositive;
};
int NoS;
int NoQ;
node * roulette;
int * positions;
int * positions2;
void createRoulette() {
roulette = new node[NoS];
positions = new int[NoS];
positions2 = new int[NoS];
int i, n2 = NoS-1, half;
int pos = 1, next, last = 1, len = 0;
positions[0] = 0;
positions2[0] = 1;
roulette[0].isPositive = false;
if(n2 % 2) // nieparzyste 1, 3, 5, ...
half = (n2 >> 1) + 1;
else // parzyste 0, 2, 4, ...
half = (n2 >> 1);
for(i = 1; i <= n2; ++i) {
next = SecondNeighbor(pos);
if(next == last)
next = FirstNeighbor(pos);
positions[next-1] = i;
positions2[i] = next;
if(i > half) {
if(!(i == half+1 && !(n2 % 2)))
--len;
roulette[next-1].isPositive = true;
}
else {
++len;
roulette[next-1].isPositive = false;
}
roulette[next-1].time = len;
last = pos;
pos = next;
}
}
inline int getDistance(const int & pos, const int & offset) {
int p = pos + offset;
if( p >= NoS )
p -= NoS;
else if( p < 0 )
p += NoS;
return roulette[ positions2[ p ]-1 ].time;
}
inline int getTime(const int & from, const int & to) {
if( from == to )
return 0;
int offset = roulette[ from-1 ].time;
if( !roulette[ from-1 ].isPositive )
offset = -offset;
return getDistance(positions[ to-1 ], offset);
}
int main() {
if(MyNodeId() > 0) {
NoS = NumberOfStudents();
NoQ = NumberOfQueries();
createRoulette();
for(int query = MyNodeId(); query <= NumberOfQueries(); query += NumberOfNodes() - 1)
{
PutInt(0, getTime( QueryFrom(query), QueryTo(query) ));
Send(0);
}
} else {
int received = 0;
while(1) {
for(int instance = 1; instance < NumberOfNodes(); ++instance) {
if(received >= NumberOfQueries()) goto end;
Receive(instance);
printf("%d\n", GetInt(instance));
++received;
}
}
}
end:
delete positions;
delete positions2;
delete roulette;
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 | #include <cstdio> #include "kollib.h" #include "message.h" using namespace std; struct node { int time; bool isPositive; }; int NoS; int NoQ; node * roulette; int * positions; int * positions2; void createRoulette() { roulette = new node[NoS]; positions = new int[NoS]; positions2 = new int[NoS]; int i, n2 = NoS-1, half; int pos = 1, next, last = 1, len = 0; positions[0] = 0; positions2[0] = 1; roulette[0].isPositive = false; if(n2 % 2) // nieparzyste 1, 3, 5, ... half = (n2 >> 1) + 1; else // parzyste 0, 2, 4, ... half = (n2 >> 1); for(i = 1; i <= n2; ++i) { next = SecondNeighbor(pos); if(next == last) next = FirstNeighbor(pos); positions[next-1] = i; positions2[i] = next; if(i > half) { if(!(i == half+1 && !(n2 % 2))) --len; roulette[next-1].isPositive = true; } else { ++len; roulette[next-1].isPositive = false; } roulette[next-1].time = len; last = pos; pos = next; } } inline int getDistance(const int & pos, const int & offset) { int p = pos + offset; if( p >= NoS ) p -= NoS; else if( p < 0 ) p += NoS; return roulette[ positions2[ p ]-1 ].time; } inline int getTime(const int & from, const int & to) { if( from == to ) return 0; int offset = roulette[ from-1 ].time; if( !roulette[ from-1 ].isPositive ) offset = -offset; return getDistance(positions[ to-1 ], offset); } int main() { if(MyNodeId() > 0) { NoS = NumberOfStudents(); NoQ = NumberOfQueries(); createRoulette(); for(int query = MyNodeId(); query <= NumberOfQueries(); query += NumberOfNodes() - 1) { PutInt(0, getTime( QueryFrom(query), QueryTo(query) )); Send(0); } } else { int received = 0; while(1) { for(int instance = 1; instance < NumberOfNodes(); ++instance) { if(received >= NumberOfQueries()) goto end; Receive(instance); printf("%d\n", GetInt(instance)); ++received; } } } end: delete positions; delete positions2; delete roulette; return (0); } |
English