#include "kollib.h" #include "message.h" #include <iostream> #include <map> #include <cmath> #define REP(x,n) for(int x=0;x<(n);++x) #define FOR(a,b,e) for(int a=b;a<=(e);++a) #define VAR(x,n) __typeof(n) x = (n) #define FOREACH(x,n) for(VAR(x,(n).begin());x!=(n).end();++x) using namespace std; map<int,int> needed; long long start, stop; void wyznacz(int prevprev, int prev, int ile) { int s1=prev, s2=prev; for(int i=0;i<ile;++i) { /// i to odległość od początku strefy if (needed.find(prev)!=needed.end()) { PutInt(0, prev); PutInt(0, start+i); Send(0); } s1 = FirstNeighbor(prev); s2 = SecondNeighbor(prev); if (prevprev==s1) { prevprev = prev; prev = s2; } else { prevprev = prev; prev = s1; } } if (MyNodeId()+1 == NumberOfNodes()) return; PutInt(MyNodeId()+1, prevprev); PutInt(MyNodeId()+1, prev); Send(MyNodeId()+1); } void Recv() { int source = Receive(-1); int a = GetInt(source); int b = GetInt(source); // cout << "received " <<source<<": "<< a << " - " << b << endl; needed[a] = b; } int main() { int prev=1, prevprev=1,s1=1,s2=1; int n = NumberOfStudents(); int m = NumberOfQueries(); if (NumberOfNodes()==1) { int dist[n]; for(int i=0;i<n;++i) { if (s1==s2) { dist[1] = 0; prev = s1 = FirstNeighbor(1); } else { dist[prev] = i; s1 = FirstNeighbor(prev); s2 = SecondNeighbor(prev); if (prevprev==s1) { prevprev = prev; prev = s2; } else { prevprev = prev; prev = s1; } } } for (int i = 1; i <= m; ++i) { int ans = abs(dist[QueryFrom(i)]-dist[QueryTo(i)]); cout << min(ans, n-ans) << endl; } } else { FOR(i,1,m) { needed[QueryFrom(i)]=-1; needed[QueryTo(i)]=-1; } start = ((long long)n)*MyNodeId()/NumberOfNodes(); stop = ((long long)n)*(MyNodeId()+1)/NumberOfNodes(); if (MyNodeId()==0) wyznacz(1, 1, stop-start); else { Receive(MyNodeId()-1); int before = GetInt(MyNodeId()-1); int current= GetInt(MyNodeId()-1); wyznacz(before, current, stop-start); } map<int,int>::iterator it; if (!MyNodeId()) for(int i=1;i<=m;++i) { it = needed.find(QueryFrom(i)); // cout << "wait for " << it->first << endl; while (it->second == -1) Recv(); // cout << "got " << it->first << " - " << it->second << endl; int wyn = it->second; it = needed.find(QueryTo(i)); // cout << "wait for " << it->first << endl; while(it->second == -1) Recv(); // cout << "got " << it->first << " - " << it->second << endl; wyn = abs(wyn-it->second); cout << min(wyn, n-wyn) << endl; } } 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 | #include "kollib.h" #include "message.h" #include <iostream> #include <map> #include <cmath> #define REP(x,n) for(int x=0;x<(n);++x) #define FOR(a,b,e) for(int a=b;a<=(e);++a) #define VAR(x,n) __typeof(n) x = (n) #define FOREACH(x,n) for(VAR(x,(n).begin());x!=(n).end();++x) using namespace std; map<int,int> needed; long long start, stop; void wyznacz(int prevprev, int prev, int ile) { int s1=prev, s2=prev; for(int i=0;i<ile;++i) { /// i to odległość od początku strefy if (needed.find(prev)!=needed.end()) { PutInt(0, prev); PutInt(0, start+i); Send(0); } s1 = FirstNeighbor(prev); s2 = SecondNeighbor(prev); if (prevprev==s1) { prevprev = prev; prev = s2; } else { prevprev = prev; prev = s1; } } if (MyNodeId()+1 == NumberOfNodes()) return; PutInt(MyNodeId()+1, prevprev); PutInt(MyNodeId()+1, prev); Send(MyNodeId()+1); } void Recv() { int source = Receive(-1); int a = GetInt(source); int b = GetInt(source); // cout << "received " <<source<<": "<< a << " - " << b << endl; needed[a] = b; } int main() { int prev=1, prevprev=1,s1=1,s2=1; int n = NumberOfStudents(); int m = NumberOfQueries(); if (NumberOfNodes()==1) { int dist[n]; for(int i=0;i<n;++i) { if (s1==s2) { dist[1] = 0; prev = s1 = FirstNeighbor(1); } else { dist[prev] = i; s1 = FirstNeighbor(prev); s2 = SecondNeighbor(prev); if (prevprev==s1) { prevprev = prev; prev = s2; } else { prevprev = prev; prev = s1; } } } for (int i = 1; i <= m; ++i) { int ans = abs(dist[QueryFrom(i)]-dist[QueryTo(i)]); cout << min(ans, n-ans) << endl; } } else { FOR(i,1,m) { needed[QueryFrom(i)]=-1; needed[QueryTo(i)]=-1; } start = ((long long)n)*MyNodeId()/NumberOfNodes(); stop = ((long long)n)*(MyNodeId()+1)/NumberOfNodes(); if (MyNodeId()==0) wyznacz(1, 1, stop-start); else { Receive(MyNodeId()-1); int before = GetInt(MyNodeId()-1); int current= GetInt(MyNodeId()-1); wyznacz(before, current, stop-start); } map<int,int>::iterator it; if (!MyNodeId()) for(int i=1;i<=m;++i) { it = needed.find(QueryFrom(i)); // cout << "wait for " << it->first << endl; while (it->second == -1) Recv(); // cout << "got " << it->first << " - " << it->second << endl; int wyn = it->second; it = needed.find(QueryTo(i)); // cout << "wait for " << it->first << endl; while(it->second == -1) Recv(); // cout << "got " << it->first << " - " << it->second << endl; wyn = abs(wyn-it->second); cout << min(wyn, n-wyn) << endl; } } return 0; } |