#include "kanapka.h"
#include "message.h"
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<set>
#include<assert.h>
using namespace std;
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define FORD(i,a,b) for(int i = a; i >= b; --i)
#define REP(i,n) FOR(i,0,(n)-1)
#define RI(i,n) FOR(i,1,n)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
#define mini(a,b) a=min(a,b)
#define maxi(a,b) a=max(a,b)
bool debug;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int inf = 1e9 + 5;
const int nax = 1e6 + 5;
struct Dane{
Dane(ll _suma=0, ll _pref=0, ll _val=0) :
suma(_suma), pref(_pref), val(_val) {}
ll suma, pref, val;
};
vector<Dane> v;
//przedzial {0 .. N-1}, id jest z przedzialu {0 .. ile_instacji - 1}
//przedzial [lewy, prawy] (wlacznie)
void get_range(ll &lewy, ll &prawy, int id, int ile_instancji, ll N) {
ll rozmiar = N / ile_instancji;
ll reszta = N % ile_instancji;
if (id < reszta) {
lewy = (rozmiar + 1) * id;
prawy = lewy + rozmiar;
return;
}
lewy = (rozmiar + 1) * reszta + rozmiar * (id - reszta);
prawy = lewy + rozmiar - 1;
}
void oblicz(ll &suma, ll &pref, ll &val, ll lewy, ll prawy) {
suma = pref = val = 0;
ll akt_war = 0;
FOR(i,lewy,prawy) {
ll taste = GetTaste(i);
suma += taste;
akt_war -= taste;
if (akt_war < 0) akt_war = 0;
val = max(val, akt_war);
pref = max(pref, -suma);
}
}
int main(int argc, char * argv[]) {
debug = argc > 1;
int ile_instancji = NumberOfNodes();
int id = MyNodeId();
ll N = GetN();
ll lewy, prawy;
get_range(lewy, prawy, id, ile_instancji, N);
//printf("%lld %lld\n",lewy, prawy);
ll suma, pref, val;
oblicz(suma, pref, val, lewy, prawy);
if (id == 0) {
v.resize(ile_instancji);
v[0] = (Dane(suma, pref, val));
FOR(i,1,ile_instancji-1) {
int source = Receive(-1);
ll _suma = GetLL(source);
ll _pref = GetLL(source);
ll _val = GetLL(source);
v[source] = Dane(_suma, _pref, _val);
}
ll suma_cal = 0;
ll dupa = 0;
ll akt_val = 0;
for (auto dane: v) {
dupa = max(max(dupa, dane.val), akt_val + dane.pref);
suma_cal += dane.suma;
akt_val -= dane.suma;
if (akt_val < 0) akt_val = 0;
}
printf("%lld\n",suma_cal + dupa);
} else {
PutLL(0,suma);
PutLL(0, pref);
PutLL(0, val);
Send(0);
}
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 | #include "kanapka.h" #include "message.h" #include<cstdio> #include<algorithm> #include<vector> #include<cstring> #include<set> #include<assert.h> using namespace std; #define FOR(i,a,b) for(int i = a; i <= b; ++i) #define FORD(i,a,b) for(int i = a; i >= b; --i) #define REP(i,n) FOR(i,0,(n)-1) #define RI(i,n) FOR(i,1,n) #define pb push_back #define mp make_pair #define st first #define nd second #define mini(a,b) a=min(a,b) #define maxi(a,b) a=max(a,b) bool debug; typedef vector<int> vi; typedef long long ll; typedef long double ld; typedef pair<int,int> pii; const int inf = 1e9 + 5; const int nax = 1e6 + 5; struct Dane{ Dane(ll _suma=0, ll _pref=0, ll _val=0) : suma(_suma), pref(_pref), val(_val) {} ll suma, pref, val; }; vector<Dane> v; //przedzial {0 .. N-1}, id jest z przedzialu {0 .. ile_instacji - 1} //przedzial [lewy, prawy] (wlacznie) void get_range(ll &lewy, ll &prawy, int id, int ile_instancji, ll N) { ll rozmiar = N / ile_instancji; ll reszta = N % ile_instancji; if (id < reszta) { lewy = (rozmiar + 1) * id; prawy = lewy + rozmiar; return; } lewy = (rozmiar + 1) * reszta + rozmiar * (id - reszta); prawy = lewy + rozmiar - 1; } void oblicz(ll &suma, ll &pref, ll &val, ll lewy, ll prawy) { suma = pref = val = 0; ll akt_war = 0; FOR(i,lewy,prawy) { ll taste = GetTaste(i); suma += taste; akt_war -= taste; if (akt_war < 0) akt_war = 0; val = max(val, akt_war); pref = max(pref, -suma); } } int main(int argc, char * argv[]) { debug = argc > 1; int ile_instancji = NumberOfNodes(); int id = MyNodeId(); ll N = GetN(); ll lewy, prawy; get_range(lewy, prawy, id, ile_instancji, N); //printf("%lld %lld\n",lewy, prawy); ll suma, pref, val; oblicz(suma, pref, val, lewy, prawy); if (id == 0) { v.resize(ile_instancji); v[0] = (Dane(suma, pref, val)); FOR(i,1,ile_instancji-1) { int source = Receive(-1); ll _suma = GetLL(source); ll _pref = GetLL(source); ll _val = GetLL(source); v[source] = Dane(_suma, _pref, _val); } ll suma_cal = 0; ll dupa = 0; ll akt_val = 0; for (auto dane: v) { dupa = max(max(dupa, dane.val), akt_val + dane.pref); suma_cal += dane.suma; akt_val -= dane.suma; if (akt_val < 0) akt_val = 0; } printf("%lld\n",suma_cal + dupa); } else { PutLL(0,suma); PutLL(0, pref); PutLL(0, val); Send(0); } return 0; } |
English