#include <algorithm> #include <cstdio> #include <vector> #include "skup.h" #include "message.h" using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define VAR(v,w) __typeof(w) v=(w) #define FORE(it,c) for(VAR(it,(c).begin());it!=(c).end();++it) #define PB push_back #define ALL(c) (c).begin(),(c).end() #define SIZE(c) ((int)(c).size()) typedef long long LL; typedef vector<int> VI; typedef vector<bool> VB; int nodes, node; VI blocks[100]; bool have[100]; int already; VB share(int id) { LL m1 = 0, m2 = 0; if (id >= 0) { if (id >= 50) m2 = 1LL << (id - 50); else m1 = 1LL << id; } REP(i,nodes-1) { REP(j,nodes) if (j != node) { PutLL(j, m1); PutLL(j, m2); Send(j); } REP(j,nodes) if (j != node) { Receive(j); m1 |= GetLL(j); m2 |= GetLL(j); } } VB shared(nodes); REP(i,min(nodes,50)) shared[i] = (m1 >> i) & 1; FOR(i,50,nodes) shared[i] = (m2 >> (i - 50)) & 1; return shared; } void sendBlock(int t, int f) { PutInt(t, f + 1); PutInt(t, SIZE(blocks[f])); REP(i,1000) PutInt(t, i < SIZE(blocks[f]) ? blocks[f][i] : 0); Send(t); } int getBlock() { int s = Receive(-1); int f = GetInt(s) - 1; int size = GetInt(s); VI block(1000); REP(i,1000) block[i] = GetInt(s); if (f < 0 || have[f]) return -1; block.resize(size); swap(block, blocks[f]); have[f] = 1; ++already; return f; } int main() { nodes = NumberOfNodes(); node = MyNodeId(); bool master = 0; VB visible = share(node); int known = count(ALL(visible), true); if (known == nodes) { VB seers = share(node); if (find(ALL(seers), true) - seers.begin() == node) master = 1; } else share(-1); int n = NumberOfCompanies(); blocks[node].resize(n); REP(i,n) blocks[node][i] = GetShareCost(i); have[node] = 1; already = 1; REP(i,nodes) if (i != node) sendBlock(i, node); while (already < known) { int f = getBlock(); if (f >= 0) REP(i,nodes) if (i != node) sendBlock(i, f); } if (!master) return 0; VI c; REP(i,nodes) FORE(it,blocks[i]) c.PB(*it); sort(ALL(c)); int cc = SIZE(c); LL res = 0; REP(i,cc) res += LL(cc - i) * c[i]; printf("%lld\n", res); }
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 | #include <algorithm> #include <cstdio> #include <vector> #include "skup.h" #include "message.h" using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define VAR(v,w) __typeof(w) v=(w) #define FORE(it,c) for(VAR(it,(c).begin());it!=(c).end();++it) #define PB push_back #define ALL(c) (c).begin(),(c).end() #define SIZE(c) ((int)(c).size()) typedef long long LL; typedef vector<int> VI; typedef vector<bool> VB; int nodes, node; VI blocks[100]; bool have[100]; int already; VB share(int id) { LL m1 = 0, m2 = 0; if (id >= 0) { if (id >= 50) m2 = 1LL << (id - 50); else m1 = 1LL << id; } REP(i,nodes-1) { REP(j,nodes) if (j != node) { PutLL(j, m1); PutLL(j, m2); Send(j); } REP(j,nodes) if (j != node) { Receive(j); m1 |= GetLL(j); m2 |= GetLL(j); } } VB shared(nodes); REP(i,min(nodes,50)) shared[i] = (m1 >> i) & 1; FOR(i,50,nodes) shared[i] = (m2 >> (i - 50)) & 1; return shared; } void sendBlock(int t, int f) { PutInt(t, f + 1); PutInt(t, SIZE(blocks[f])); REP(i,1000) PutInt(t, i < SIZE(blocks[f]) ? blocks[f][i] : 0); Send(t); } int getBlock() { int s = Receive(-1); int f = GetInt(s) - 1; int size = GetInt(s); VI block(1000); REP(i,1000) block[i] = GetInt(s); if (f < 0 || have[f]) return -1; block.resize(size); swap(block, blocks[f]); have[f] = 1; ++already; return f; } int main() { nodes = NumberOfNodes(); node = MyNodeId(); bool master = 0; VB visible = share(node); int known = count(ALL(visible), true); if (known == nodes) { VB seers = share(node); if (find(ALL(seers), true) - seers.begin() == node) master = 1; } else share(-1); int n = NumberOfCompanies(); blocks[node].resize(n); REP(i,n) blocks[node][i] = GetShareCost(i); have[node] = 1; already = 1; REP(i,nodes) if (i != node) sendBlock(i, node); while (already < known) { int f = getBlock(); if (f >= 0) REP(i,nodes) if (i != node) sendBlock(i, f); } if (!master) return 0; VI c; REP(i,nodes) FORE(it,blocks[i]) c.PB(*it); sort(ALL(c)); int cc = SIZE(c); LL res = 0; REP(i,cc) res += LL(cc - i) * c[i]; printf("%lld\n", res); } |