#include <bits/stdc++.h> #include "futbol.h" #include "message.h" using namespace std; #define FOR(i, x) for( int i = 1; i <=x; i++ ) #define REP(i, x) for( int i = 0; i < x; i++ ) int NODES; int my_nr; int n; int k; int p; int my_left; int my_right; int range; int silnia_lewa = 1; int wynik = 0; inline int mnoz(long long a, int b){ return (a * b) % p; } inline int dodaj(long long a, int b){ return (a + b) % p; } inline int quick_pow(int a, int k){ int init_a = a; int akt = 1; int wyn = 1; while( akt <= k ){ if( akt & k ) wyn = mnoz(wyn, a); a = mnoz(a, a); akt <<= 1; } //cout << "LICZENIE " << init_a << " " << wyn << " " << mnoz(init_a, wyn) << endl; return wyn; } inline int odwr(int a){ return quick_pow(a, p-2); } void init(){ NODES = NumberOfNodes(); my_nr = MyNodeId(); n = GetN(); k = GetK(); p = GetP(); range = (n / NODES) + 1; my_left = range * my_nr; my_right = min(range * (my_nr+1), n); } const int MAX_RNG = 10000000 + 1000000; int silnia_prawa[MAX_RNG]; void licz_wlasny(){ //cout << my_right << " " << my_left <<" " << MAX_RNG << endl; silnia_prawa[max(my_right-my_left, 0)] = 1; for( int i = my_right-1; i >= my_left; i-- ) silnia_prawa[i-my_left] = mnoz(silnia_prawa[i-my_left+1], i+1); for( int i = my_left; i < my_right; i++ ){ if( i > 0 ) silnia_lewa = mnoz(silnia_lewa, (n-i+1)); if( i <= k ) wynik = dodaj(wynik, mnoz(silnia_lewa, silnia_prawa[i-my_left])); } //cout << my_left << " " << my_right << " " << silnia_lewa << " " << silnia_prawa[0] << " " << wynik << endl; } void zwroc_wynik(){ //cout << my_left <<" " << my_right << " " << do_licz << " " << do_mian << " "<< wynik << endl; if( my_nr != 0 ){ if( n == 0 ){ PutInt(0, -1); PutInt(0, -1); PutInt(0, -1); } PutInt(0, silnia_lewa); PutInt(0, silnia_prawa[0]); PutInt(0, wynik); Send(0); } else{ const int MAX_N = 110; int sil_l[MAX_N]; int sil_r[MAX_N]; int wyncze[MAX_N]; sil_l[0] = silnia_lewa; sil_r[0] = silnia_prawa[0]; wyncze[0] = wynik; FOR(i, NODES-1){ Receive(i); sil_l[i] = GetInt(i); sil_r[i] = GetInt(i); wyncze[i] = GetInt(i); } if( sil_l[NODES-1] == -1 ){ my_right = n; wynik = 0; NODES = 1; licz_wlasny(); sil_l[0] = silnia_lewa; sil_r[0] = silnia_prawa[0]; wyncze[0] = wynik; } int real_wynik = 0; int silnia_right = 1; int silnia_left = 1; REP(i, NODES) silnia_right = mnoz(silnia_right, sil_r[i]); REP(i, NODES){ //cout << i << " " << silnia_left << " " << silnia_right << " " << real_wynik << endl; //cout << sil_r[i] << " " << odwr(sil_r[i]) << " " << mnoz(sil_r[i], odwr(sil_r[i])) << endl; silnia_right = mnoz(silnia_right, odwr(sil_r[i])); real_wynik = dodaj(real_wynik, mnoz(wyncze[i], mnoz(silnia_left, silnia_right))); silnia_left = mnoz(silnia_left, sil_l[i]); } int n_silnia = 1; REP(i, NODES) n_silnia = mnoz(n_silnia, sil_r[i]); real_wynik = mnoz(real_wynik, odwr(n_silnia)); if( k == n ) real_wynik++; cout << real_wynik << endl; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); //p = 999999937; //if( MyNodeId() == 0 ) for( int i = 1; i < p; i++ ) cout << mnoz(i, odwr(i)) << endl; init(); licz_wlasny(); zwroc_wynik(); 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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #include <bits/stdc++.h> #include "futbol.h" #include "message.h" using namespace std; #define FOR(i, x) for( int i = 1; i <=x; i++ ) #define REP(i, x) for( int i = 0; i < x; i++ ) int NODES; int my_nr; int n; int k; int p; int my_left; int my_right; int range; int silnia_lewa = 1; int wynik = 0; inline int mnoz(long long a, int b){ return (a * b) % p; } inline int dodaj(long long a, int b){ return (a + b) % p; } inline int quick_pow(int a, int k){ int init_a = a; int akt = 1; int wyn = 1; while( akt <= k ){ if( akt & k ) wyn = mnoz(wyn, a); a = mnoz(a, a); akt <<= 1; } //cout << "LICZENIE " << init_a << " " << wyn << " " << mnoz(init_a, wyn) << endl; return wyn; } inline int odwr(int a){ return quick_pow(a, p-2); } void init(){ NODES = NumberOfNodes(); my_nr = MyNodeId(); n = GetN(); k = GetK(); p = GetP(); range = (n / NODES) + 1; my_left = range * my_nr; my_right = min(range * (my_nr+1), n); } const int MAX_RNG = 10000000 + 1000000; int silnia_prawa[MAX_RNG]; void licz_wlasny(){ //cout << my_right << " " << my_left <<" " << MAX_RNG << endl; silnia_prawa[max(my_right-my_left, 0)] = 1; for( int i = my_right-1; i >= my_left; i-- ) silnia_prawa[i-my_left] = mnoz(silnia_prawa[i-my_left+1], i+1); for( int i = my_left; i < my_right; i++ ){ if( i > 0 ) silnia_lewa = mnoz(silnia_lewa, (n-i+1)); if( i <= k ) wynik = dodaj(wynik, mnoz(silnia_lewa, silnia_prawa[i-my_left])); } //cout << my_left << " " << my_right << " " << silnia_lewa << " " << silnia_prawa[0] << " " << wynik << endl; } void zwroc_wynik(){ //cout << my_left <<" " << my_right << " " << do_licz << " " << do_mian << " "<< wynik << endl; if( my_nr != 0 ){ if( n == 0 ){ PutInt(0, -1); PutInt(0, -1); PutInt(0, -1); } PutInt(0, silnia_lewa); PutInt(0, silnia_prawa[0]); PutInt(0, wynik); Send(0); } else{ const int MAX_N = 110; int sil_l[MAX_N]; int sil_r[MAX_N]; int wyncze[MAX_N]; sil_l[0] = silnia_lewa; sil_r[0] = silnia_prawa[0]; wyncze[0] = wynik; FOR(i, NODES-1){ Receive(i); sil_l[i] = GetInt(i); sil_r[i] = GetInt(i); wyncze[i] = GetInt(i); } if( sil_l[NODES-1] == -1 ){ my_right = n; wynik = 0; NODES = 1; licz_wlasny(); sil_l[0] = silnia_lewa; sil_r[0] = silnia_prawa[0]; wyncze[0] = wynik; } int real_wynik = 0; int silnia_right = 1; int silnia_left = 1; REP(i, NODES) silnia_right = mnoz(silnia_right, sil_r[i]); REP(i, NODES){ //cout << i << " " << silnia_left << " " << silnia_right << " " << real_wynik << endl; //cout << sil_r[i] << " " << odwr(sil_r[i]) << " " << mnoz(sil_r[i], odwr(sil_r[i])) << endl; silnia_right = mnoz(silnia_right, odwr(sil_r[i])); real_wynik = dodaj(real_wynik, mnoz(wyncze[i], mnoz(silnia_left, silnia_right))); silnia_left = mnoz(silnia_left, sil_l[i]); } int n_silnia = 1; REP(i, NODES) n_silnia = mnoz(n_silnia, sil_r[i]); real_wynik = mnoz(real_wynik, odwr(n_silnia)); if( k == n ) real_wynik++; cout << real_wynik << endl; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); //p = 999999937; //if( MyNodeId() == 0 ) for( int i = 1; i < p; i++ ) cout << mnoz(i, odwr(i)) << endl; init(); licz_wlasny(); zwroc_wynik(); return 0; } |