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
#include <iostream>
#include "message.h"
#include "teatr.h"
#include <vector>


using namespace std;


int main()
{
    int L = GetN(); // dlugosc danych
    int N = NumberOfNodes();

    const int max_wzrost = 4; // maksymalny wzrost-1 - zakladamy wzrost<=5 !!!

    vector<uint32_t> zliczenia(max_wzrost, 0); // zlicz kolejno (wzrost-1) >0, >1, >2, >3


    if (MyNodeId()>0)
    {
        //dzielimy dane na L przedzialow, zliczenia w przedzialach od 0 do L-1
        for (int ii = (MyNodeId()-1)*L/N; ii<MyNodeId()*L/N; ii++)
        {
            int wzrost = GetElement(ii)-1; //(wzrost-1) nalezy do {0,1,2,3,4}
            for (int z = 0; z<4; z++)
            {
                if (wzrost>z)
                    zliczenia[z]++;
            }
        }
        for (int z=0; z<4; z++)
        {
            PutInt(0, zliczenia[z]);
        }
        Send(0);

        //odbierz sumy skumulowane od instatcji nr 0
        Receive(0);
        for (int z=0; z<4; z++)
        {
            int temp = GetInt(0);
            zliczenia[z]=temp;
        }
    }

    else // MyNodeId()==0
    {
        // zlicz sumy skumulowane z przedzialow od przed_0 do przed_L (L-1)
        vector<vector<uint32_t>> sumy_kumul;
        sumy_kumul.push_back(zliczenia); // same zera - suma dla przed_0

        for (int id = 1; id<N; id++)
        {
            Receive(id);
            sumy_kumul.push_back(zliczenia);
            for (int z=0; z<4; z++)
            {
                int temp = GetInt(id);
                sumy_kumul[id][z] = temp + sumy_kumul[id-1][z];
                // Uwaga! kumulacja sum korzysta z kolejnosci czytania!
            }
        }

        // wyslij instancjom sumy skumulowane
        for (int id = 1; id<N; id++)
        {
            for (int z=0; z<4; z++)
            {
                PutInt(id, sumy_kumul[id][z]);
            }
            Send(id);
        }        
    }


    // policz klotnie na podprzedzialach
    long long klotnie = 0;
    for (int ii = MyNodeId()*L/N; ii<(MyNodeId()+1)*L/N; ii++)
    {
        // posiadamy tablice zliczen el.>a (a=1,2,3,4) na wszystkich
        // podprzedzialach wczesniejszych niz obecny
        // liczymy klotnie i uzupelniamy tablice na biezaco o nowe zliczenia
        int wzrost = GetElement(ii)-1;
        if (wzrost<max_wzrost)
            klotnie += zliczenia[wzrost];
        for (int z = 0; z<4; z++)
            if (wzrost>z)
                zliczenia[z]++;
    }    


    // policz calkowita liczbe klotni
    if (MyNodeId()>0)
    {
        PutLL(0, klotnie);
        Send(0);
    }
    else //MyNodeId()==0
    {
        for (int id = 1; id<N; id++)
        {
            Receive(id);
            long long temp = GetLL(id);
            klotnie +=temp;
        }
        cout<<klotnie<<endl;
    }


    return 0;
}