Advertisement
Guest User

Untitled

a guest
Dec 8th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.90 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include "dzialka.h"
  3. #include "message.h"
  4.  
  5. using namespace std;
  6.  
  7. #define REP(i, x) for( int i = 0; i < x; i++ )
  8. #define FOR(i, x) for( int i = 1; i <=x; i++ )
  9. #define BACK(i, x) for( int i = x; i >=1; i-- )
  10. #define BACK_REP(i, x) for( int i = x-1; i >=0; i-- )
  11. #define MP make_pair
  12. #define ST first
  13. #define ND second
  14. #define LL long long
  15.  
  16. typedef pair<int, int> PI;
  17.  
  18. const int MAX_WIDTH = 75010;
  19. int NODES;
  20.  
  21. int h;
  22. int w;
  23. int myself = MyNodeId();
  24.  
  25. int premie[MAX_WIDTH];
  26. int specjalne_premie[MAX_WIDTH];
  27. bool zastap[MAX_WIDTH];
  28.  
  29. int przedzial;
  30. int moja_gora;
  31. int moj_dol;
  32.  
  33. void znajdz_zakres(){ //liczy procesowi, które wiersze tablicy będzie przerabiał
  34.     przedzial = (h / NODES) + 1;
  35.     moja_gora = myself * przedzial;
  36.     moj_dol = min((myself + 1) * przedzial, h);
  37. }
  38.  
  39. /*  Każdemu procesowi liczy, jaka jest wysokość "słupa" dobrych elementów ponad jego przedziałem,
  40.     wartość ta będzie trzymana w tablicy premie[].
  41.     specjalne_premie[] trzymają wysokość takiego słupa dla segmentu przetwarzanego przez dany proces
  42.     (kandydat do przekazania następnemu procesowi dla jego segmentu), którą być może trzeba poprawić
  43.     wynikiem zwróconym z segmentu przetwarzającego wyższy fragment (poprawia druga pętla, wysyła - trzecia).
  44.     zastap sprawdza, czy gdzieś na danym segmencie mamy zły element, co oznaczałoby, że nie możemy zwiększyć
  45.     wyniku o to, co dostaliśmy z wyższej części tablicy (można by było zamiast sprawdzania zastap[k] sprawdzać,
  46.     czy moja_gora - moj_dol == specjalne_premie[k]).
  47. */
  48. void znajdz_premie(){
  49.     REP(k, w){
  50.         specjalne_premie[k] = 0;
  51.         zastap[k] = false;
  52.         for( int j = moja_gora; j < moj_dol; j++ )
  53.             if( IsUsableCell(j, k) ) specjalne_premie[k]++;
  54.             else{
  55.                 specjalne_premie[k] = 0;
  56.                 zastap[k] = true;
  57.             }
  58.     }
  59.     if( myself != 0 ){
  60.         Receive(myself - 1);
  61.         REP(k, w){
  62.             premie[k] = GetInt(myself - 1);
  63.             if( zastap[k] == false )
  64.                 specjalne_premie[k] += premie[k];
  65.         }
  66.     }
  67.  
  68.     if( myself < NODES-1 ){
  69.         REP(k, w) PutInt(myself + 1, specjalne_premie[k]);
  70.         Send(myself + 1);
  71.     }
  72. }
  73.  
  74. inline LL komb(LL a){
  75.     return a * (a+1) /2;
  76. }
  77.  
  78. void znajdz_rozwa(){ //działkowa magia wykonana na każdym wierszu, na którym działa ten proces, wynik kumulowany w 0
  79.     LL wynik = 0;
  80.     stack<PI> propo;
  81.     for( int j = moja_gora; j < moj_dol; j++ ){
  82.         while(!propo.empty()) propo.pop();
  83.         propo.push({-1, -1});
  84.         REP(k, w){
  85.             if( IsUsableCell(j, k) ) premie[k]++;
  86.             else premie[k] = 0;
  87.             int new_pos = k;
  88.             while(propo.top().ST >= premie[k]){
  89.                 int old_height = propo.top().ST;
  90.                 int old_pos = propo.top().ND;
  91.                 propo.pop();
  92.                 int new_height = propo.top().ST;
  93.                 wynik += komb(k - old_pos) * (old_height-max(new_height, premie[k]));
  94.                 new_pos = old_pos;
  95.             }
  96.             propo.push({premie[k], new_pos});
  97.         }
  98.             premie[w] = 0;
  99.             while(propo.top().ST > premie[w]){
  100.                 int old_height = propo.top().ST;
  101.                 int old_pos = propo.top().ND;
  102.                 propo.pop();
  103.                 int new_height = propo.top().ST;
  104.                 wynik += komb(w - old_pos) * (old_height-max(new_height, 0));
  105.             }
  106.     }
  107.  
  108.     PutLL(0, wynik);
  109.     Send(0);
  110.  
  111.     LL real_wynik = 0;
  112.     if( myself == 0 ){
  113.         REP(i, NODES){
  114.             Receive(i);
  115.             real_wynik += GetLL(i);
  116.         }
  117.         cout << real_wynik << endl;
  118.     }
  119. }
  120.  
  121. int main(){
  122.     h = GetFieldHeight();
  123.     w = GetFieldWidth();
  124.     NODES = NumberOfNodes();
  125.  
  126.     znajdz_zakres();
  127.     znajdz_premie();
  128.  
  129.     znajdz_rozwa();
  130.  
  131.     return 0;
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement