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
#include <bits/stdc++.h>
#include <unordered_set>
#include "dzialka.h"
#include "message.h"

using namespace std;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define klar(v) memset(v, 0, sizeof(v))
#define bust ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define gcd(a, b) __gcd(a, b);
#define debug cout << "chuj" << endl;
#define endl "\n"

typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef vector<long long> vll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
const int maxis = 99;

int wys[2][75010];
ll dod[75010];
ll kek[75010];
ll pref;
stack <pii> stck;

void add(int val, int it){
    while(stck.top().nd != 0 and stck.top().st >= val){
        pref -= kek[stck.top().st];
        stck.pop();
    }
    //    cout << val << endl;
    kek[val] = 1LL*(it-stck.top().nd)*val;
    //    if(val == 0)cout << pref << endl;
    //    if(pref < 0)debug
    pref += kek[val];
    if(val == 0)pref = 0;
    stck.push(mp(val, it));
}

int main(){
    int n, m;
    ll dd = 0;
    ll ret = 0;
    int act = MyNodeId();
    if(act == 0){
        n = GetFieldHeight();
        m = GetFieldWidth();
    }
    else{
        Receive(act-1);
        n = GetInt(act-1);
        m = GetInt(act-1);
    }
    if(act < maxis){
        PutInt(act+1, n);
        PutInt(act+1, m);
        Send(act+1);
    }
    int it = 1+act*750;
    int k = act*750;
    if(it <= n){
        for(int i = it; i < min(it+750, n+1); i++){
            for(int j = 1; j <= m; j++){
                if(IsUsableCell(i-1, j-1))
                    wys[0][j] += wys[1][j]+1;
                wys[1][j] = wys[0][j];
                wys[0][j] = 0;
            }
        }
        if(act > 0){
            Receive(act-1);
            for(int i = 1; i <= m; i++){
                dod[i] += GetInt(act-1);
                if(i%15000 == 0)Receive(act-1);
            }
        }
        if(act < maxis){
            for(int i = 1; i <= m; i++){
                if(wys[1][i] == 750)wys[1][i] += dod[i];
                PutInt(act+1, wys[1][i]);
                if(i%15000 == 0)Send(act+1);
            }
            if(m%15000)
                Send(act+1);
        }
//        klar(wys);
        for(int i = 1; i <= m; i++)wys[1][i] = dod[i];
//                cout << it << endl;
//                for(int i = 100; i <= 110; i++)cout << wys[1][i] << " ";
//                cout << endl;
        for(int i = it; i < min(it+750, n+1); i++){
            stck.push(mp(0, 0));
            for(int j = 1; j <= m; j++){
                if(IsUsableCell(i-1, j-1))
                    wys[0][j] += wys[1][j]+1;
                add(wys[0][j], j);
                ret += pref;
                wys[1][j] = wys[0][j];
                wys[0][j] = 0;
            }
            while(stck.size())stck.pop();
            pref = 0;
        }
    }
    //    cout << act << endl;
    if(act > 0){
        //        cout << act << " " << ret << endl;
        PutLL(0, ret);
        Send(0);
    }
    else{
        //        cout << act << " " << ret << endl;
        for(int i = 1; i <= maxis; i++){
            Receive(i);
            ret += GetLL(i);
        }
        cout << ret;
    }
}