#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "kanapka.h"
#include "message.h"
#define DBG 0
typedef struct {
    long long lidx, ridx, sum;
    long long maxl1, maxl1idx, maxr1, maxr1idx;
    long long maxl2, maxl2idx, maxr2, maxr2idx;
} node_t;
int main(void)
{
    int NodeN = NumberOfNodes();
    int NodeI = MyNodeId();
    int NodeX;
    long long N = GetN();
    long long l = N / NodeN;
    long long m = N % NodeN;
    long long i;
    node_t node, node2;
    memset(&node, 0x0, sizeof (node));
    if (NodeI < m) {
        node.lidx = NodeI * (l + 1);
        node.ridx = (NodeI + 1) * (l + 1);
    }
    else {
        node.lidx = NodeI * l + m;
        node.ridx = (NodeI + 1) * l + m;
    }
    node.maxl1 = LLONG_MIN;
    node.maxr1 = LLONG_MIN;
    for (i = node.lidx; i < node.ridx; i++) {
        node.sum += GetTaste(i);
        if (node.sum > node.maxl1) {
            node.maxl1 = node.sum;
            node.maxl1idx = i;
        }
    }
    node.sum = 0;
    for (i = node.ridx - 1; i >= node.lidx; i--) {
        node.sum += GetTaste(i);
        if (node.sum > node.maxr1) {
            node.maxr1 = node.sum;
            node.maxr1idx = i;
        }
    }
    if (node.maxl1idx <= node.maxr1idx || node.maxl1 == node.maxr1) {
        node.maxl2 = node.maxl1;
        node.maxl2idx = node.maxl1idx;
        node.maxr2 = node.maxr1;
        node.maxr2idx = node.maxr1idx;
    }
    else if (node.maxl1 > node.maxr1) {
        long long s = 0;
        node.maxl2 = node.maxl1;
        node.maxl2idx = node.maxl1idx;
        node.maxr2 = LLONG_MIN;
        for (i = node.ridx - 1; i > node.maxl1idx; i--) {
            s += GetTaste(i);
            if (s > node.maxr2) {
                node.maxr2 = s;
                node.maxr2idx = i;
            }
        }
    }
    else {
        long long s = 0;
        node.maxr2 = node.maxr1;
        node.maxr2idx = node.maxr1idx;
        node.maxl2 = LLONG_MIN;
        for (i = node.lidx; i < node.maxr1idx; i++) {
            s += GetTaste(i);
            if (s > node.maxl2) {
                node.maxl2 = s;
                node.maxl2idx = i;
            }
        }
    }
    for (NodeX = 1; NodeX < NodeN; NodeX <<= 1) {
        int Node2 = NodeI ^ NodeX;
        node_t tmp;
        if (Node2 < NodeI) {
            PutLL(Node2, node.lidx);
            PutLL(Node2, node.ridx);
            PutLL(Node2, node.sum);
            PutLL(Node2, node.maxl1);
            PutLL(Node2, node.maxl1idx);
            PutLL(Node2, node.maxr1);
            PutLL(Node2, node.maxr1idx);
            PutLL(Node2, node.maxl2);
            PutLL(Node2, node.maxl2idx);
            PutLL(Node2, node.maxr2);
            PutLL(Node2, node.maxr2idx);
            Send(Node2);
            return 0;
        }
        if (Node2 >= NodeN)
            continue;
        Receive(Node2);
        node2.lidx = GetLL(Node2);
        node2.ridx = GetLL(Node2);
        node2.sum = GetLL(Node2);
        node2.maxl1 = GetLL(Node2);
        node2.maxl1idx = GetLL(Node2);
        node2.maxr1 = GetLL(Node2);
        node2.maxr1idx = GetLL(Node2);
        node2.maxl2 = GetLL(Node2);
        node2.maxl2idx = GetLL(Node2);
        node2.maxr2 = GetLL(Node2);
        node2.maxr2idx = GetLL(Node2);
        if (node2.lidx >= node2.ridx)
            continue;
#if DBG
        printf("O %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, Node2, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx);
        printf("R %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, Node2, node2.lidx, node2.ridx, node2.ridx - node2.lidx, node2.sum, node2.maxl1, node2.maxr1, node2.maxl1idx, node2.maxr1idx, node2.maxl2, node2.maxr2, node2.maxl2idx, node2.maxr2idx);
        memset (&tmp, 0x0, sizeof(tmp));
#endif
        tmp.lidx = node.lidx;
        tmp.ridx = node.ridx;
        tmp.sum = node.sum + node2.sum;
        if (node.maxl1 >= node.sum + node2.maxl1) {
            tmp.maxl1 = node.maxl1;
            tmp.maxl1idx = node.maxl1idx;
        }
        else {
            tmp.maxl1 = node.sum + node2.maxl1;
            tmp.maxl1idx = node2.maxl1idx;
        }
        if (node2.maxr1 >= node2.sum + node.maxr1) {
            tmp.maxr1 = node2.maxr1;
            tmp.maxr1idx = node2.maxr1idx;
        }
        else {
            tmp.maxr1 = node2.sum + node.maxr1;
            tmp.maxr1idx = node.maxr1idx;
        }
        if (tmp.maxl1idx <= tmp.maxr1idx || tmp.maxl1 == tmp.maxr1) {
            tmp.maxl2 = tmp.maxl1;
            tmp.maxl2idx = tmp.maxl1idx;
            tmp.maxr2 = tmp.maxr1;
            tmp.maxr2idx = tmp.maxr1idx;
        }
        else if (tmp.maxl1 > tmp.maxr1) {
            tmp.maxl2 = tmp.maxl1;
            tmp.maxl2idx = tmp.maxl1idx;
            tmp.maxr2 = node2.maxr2;
            tmp.maxr2idx = node2.maxr2idx;
        }
        else {
            tmp.maxr2 = tmp.maxr1;
            tmp.maxr2idx = tmp.maxr1idx;
            tmp.maxl2 = node.maxl2;
            tmp.maxl2idx = node.maxl2idx;
        }
        node = tmp;
#if DBG
        printf("M %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n\n", NodeI, Node2, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx);
#endif
    }
#if DBG
    printf("E %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, -1, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx);
#endif
    if (node.maxl2idx < node.maxr2idx)
        i = node.maxl2 + node.maxr2;
    else if (node.maxl2 >= node.maxr2)
        i = node.maxl2;
    else 
        i = node.maxr2;
    if (i < 0)
        i = 0;
    printf("%lld\n", i);
    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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include "kanapka.h" #include "message.h" #define DBG 0 typedef struct { long long lidx, ridx, sum; long long maxl1, maxl1idx, maxr1, maxr1idx; long long maxl2, maxl2idx, maxr2, maxr2idx; } node_t; int main(void) { int NodeN = NumberOfNodes(); int NodeI = MyNodeId(); int NodeX; long long N = GetN(); long long l = N / NodeN; long long m = N % NodeN; long long i; node_t node, node2; memset(&node, 0x0, sizeof (node)); if (NodeI < m) { node.lidx = NodeI * (l + 1); node.ridx = (NodeI + 1) * (l + 1); } else { node.lidx = NodeI * l + m; node.ridx = (NodeI + 1) * l + m; } node.maxl1 = LLONG_MIN; node.maxr1 = LLONG_MIN; for (i = node.lidx; i < node.ridx; i++) { node.sum += GetTaste(i); if (node.sum > node.maxl1) { node.maxl1 = node.sum; node.maxl1idx = i; } } node.sum = 0; for (i = node.ridx - 1; i >= node.lidx; i--) { node.sum += GetTaste(i); if (node.sum > node.maxr1) { node.maxr1 = node.sum; node.maxr1idx = i; } } if (node.maxl1idx <= node.maxr1idx || node.maxl1 == node.maxr1) { node.maxl2 = node.maxl1; node.maxl2idx = node.maxl1idx; node.maxr2 = node.maxr1; node.maxr2idx = node.maxr1idx; } else if (node.maxl1 > node.maxr1) { long long s = 0; node.maxl2 = node.maxl1; node.maxl2idx = node.maxl1idx; node.maxr2 = LLONG_MIN; for (i = node.ridx - 1; i > node.maxl1idx; i--) { s += GetTaste(i); if (s > node.maxr2) { node.maxr2 = s; node.maxr2idx = i; } } } else { long long s = 0; node.maxr2 = node.maxr1; node.maxr2idx = node.maxr1idx; node.maxl2 = LLONG_MIN; for (i = node.lidx; i < node.maxr1idx; i++) { s += GetTaste(i); if (s > node.maxl2) { node.maxl2 = s; node.maxl2idx = i; } } } for (NodeX = 1; NodeX < NodeN; NodeX <<= 1) { int Node2 = NodeI ^ NodeX; node_t tmp; if (Node2 < NodeI) { PutLL(Node2, node.lidx); PutLL(Node2, node.ridx); PutLL(Node2, node.sum); PutLL(Node2, node.maxl1); PutLL(Node2, node.maxl1idx); PutLL(Node2, node.maxr1); PutLL(Node2, node.maxr1idx); PutLL(Node2, node.maxl2); PutLL(Node2, node.maxl2idx); PutLL(Node2, node.maxr2); PutLL(Node2, node.maxr2idx); Send(Node2); return 0; } if (Node2 >= NodeN) continue; Receive(Node2); node2.lidx = GetLL(Node2); node2.ridx = GetLL(Node2); node2.sum = GetLL(Node2); node2.maxl1 = GetLL(Node2); node2.maxl1idx = GetLL(Node2); node2.maxr1 = GetLL(Node2); node2.maxr1idx = GetLL(Node2); node2.maxl2 = GetLL(Node2); node2.maxl2idx = GetLL(Node2); node2.maxr2 = GetLL(Node2); node2.maxr2idx = GetLL(Node2); if (node2.lidx >= node2.ridx) continue; #if DBG printf("O %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, Node2, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx); printf("R %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, Node2, node2.lidx, node2.ridx, node2.ridx - node2.lidx, node2.sum, node2.maxl1, node2.maxr1, node2.maxl1idx, node2.maxr1idx, node2.maxl2, node2.maxr2, node2.maxl2idx, node2.maxr2idx); memset (&tmp, 0x0, sizeof(tmp)); #endif tmp.lidx = node.lidx; tmp.ridx = node.ridx; tmp.sum = node.sum + node2.sum; if (node.maxl1 >= node.sum + node2.maxl1) { tmp.maxl1 = node.maxl1; tmp.maxl1idx = node.maxl1idx; } else { tmp.maxl1 = node.sum + node2.maxl1; tmp.maxl1idx = node2.maxl1idx; } if (node2.maxr1 >= node2.sum + node.maxr1) { tmp.maxr1 = node2.maxr1; tmp.maxr1idx = node2.maxr1idx; } else { tmp.maxr1 = node2.sum + node.maxr1; tmp.maxr1idx = node.maxr1idx; } if (tmp.maxl1idx <= tmp.maxr1idx || tmp.maxl1 == tmp.maxr1) { tmp.maxl2 = tmp.maxl1; tmp.maxl2idx = tmp.maxl1idx; tmp.maxr2 = tmp.maxr1; tmp.maxr2idx = tmp.maxr1idx; } else if (tmp.maxl1 > tmp.maxr1) { tmp.maxl2 = tmp.maxl1; tmp.maxl2idx = tmp.maxl1idx; tmp.maxr2 = node2.maxr2; tmp.maxr2idx = node2.maxr2idx; } else { tmp.maxr2 = tmp.maxr1; tmp.maxr2idx = tmp.maxr1idx; tmp.maxl2 = node.maxl2; tmp.maxl2idx = node.maxl2idx; } node = tmp; #if DBG printf("M %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n\n", NodeI, Node2, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx); #endif } #if DBG printf("E %4d %4d %4lld %4lld %4lld | %4lld | %4lld %4lld %4lld %4lld | %4lld %4lld %4lld %4lld\n", NodeI, -1, node.lidx, node.ridx, node.ridx - node.lidx, node.sum, node.maxl1, node.maxr1, node.maxl1idx, node.maxr1idx, node.maxl2, node.maxr2, node.maxl2idx, node.maxr2idx); #endif if (node.maxl2idx < node.maxr2idx) i = node.maxl2 + node.maxr2; else if (node.maxl2 >= node.maxr2) i = node.maxl2; else i = node.maxr2; if (i < 0) i = 0; printf("%lld\n", i); return 0; } | 
 
            
         English
                    English