#include <algorithm> #include <cstdio> #include "kanapka.h" #include "message.h" using namespace std; typedef long long LL; struct BlockDesc { LL sum; LL MaxLeft; LL MaxRight; LL MaxBoth; }; void print(BlockDesc * block) { printf("sum = %lld, MaxLeft = %lld, MaxRight = %lld, MaxBoth = %lld\n", block->sum, block->MaxLeft, block->MaxRight, block->MaxBoth); } int M; #define MAX_LEN 100 LL tab[MAX_LEN]; struct BlockCalcs { LL sumLeft[MAX_LEN]; LL sumRight[MAX_LEN]; LL MaxLeft[MAX_LEN]; LL MaxRight[MAX_LEN]; LL MaxBoth[MAX_LEN]; }; BlockCalcs block; #define MAX_INSTANCES 101 BlockDesc splitted[MAX_INSTANCES]; int InstCounter = 0; LL GetVal(LL n, LL offset) { //return tab[offset+n]; return (GetTaste(offset+n)); } void calcBlock(LL offset, LL length) { int M = length; BlockDesc res; if( M > 1 ) { /*printf("tab: "); for(int i = 0; i < M; ++i) printf("%lld ", GetVal(i, offset));*/ block.sumLeft[0] = GetVal(0, offset); block.sumRight[M-1] = GetVal(M-1, offset); block.MaxLeft[0] = max(GetVal(0, offset), 0LL); block.MaxRight[M-1] = max(GetVal(M-1, offset), 0LL); for(int i = 1; i < M; ++i) { block.sumLeft[i] = block.sumLeft[i-1] + GetVal(i, offset); block.MaxLeft[i] = max(block.sumLeft[i], block.MaxLeft[i-1]); } for(int i = M-2; i >= 0; --i) { block.sumRight[i] = block.sumRight[i+1] + GetVal(i, offset); block.MaxRight[i] = max(block.sumRight[i], block.MaxRight[i+1]); } for(int i = 0; i < M-1; ++i) { block.MaxBoth[i] = block.MaxLeft[i] + block.MaxRight[i+1]; } res.sum = block.sumLeft[M-1]; res.MaxLeft = block.MaxLeft[0]; res.MaxRight = block.MaxRight[0]; res.MaxBoth = block.MaxBoth[0]; for(int i = 1; i < M-1; ++i) { res.MaxLeft = max(res.MaxLeft, block.MaxLeft[i]); res.MaxRight = max(res.MaxRight, block.MaxRight[i]); res.MaxBoth = max(res.MaxBoth, block.MaxBoth[i]); } } else { res.sum = GetVal(0, offset); res.MaxLeft = max(0LL, GetVal(0, offset)); res.MaxRight = res.MaxLeft; res.MaxBoth = res.MaxRight; } //splitted[InstCounter++] = res; PutLL(0, res.sum); PutLL(0, res.MaxLeft); PutLL(0, res.MaxRight); PutLL(0, res.MaxBoth); Send(0); /*printf("\nsumLeft = "); for(int i = 0; i < M; ++i) printf("%lld ", block.sumLeft[i]); printf("\nsumRight = "); for(int i = 0; i < M; ++i) printf("%lld ", block.sumRight[i]); printf("\nMaxLeft = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxLeft[i]); printf("\nMaxRight = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxRight[i]); printf("\nMaxBoth = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxBoth[i]); printf("\n\n");*/ } struct MergeCalcs { LL sumLeft[MAX_INSTANCES]; LL sumRight[MAX_INSTANCES]; LL MaxLeft[MAX_INSTANCES]; LL MaxRight[MAX_INSTANCES]; LL MaxBoth[MAX_INSTANCES]; }; MergeCalcs mergeTabs; LL merge(LL instances) { int K = instances; /*for(int i = 0; i < K; ++i) { print(splitted + i); }*/ MergeCalcs res; mergeTabs.sumLeft[0] = splitted[0].sum; mergeTabs.sumRight[K-1] = splitted[K-1].sum; mergeTabs.MaxLeft[0] = splitted[0].MaxLeft; mergeTabs.MaxRight[K-1] = splitted[K-1].MaxRight; for(int i = 1; i < K; ++i) { mergeTabs.sumLeft[i] = mergeTabs.sumLeft[i-1] + splitted[i].sum; mergeTabs.MaxLeft[i] = max(mergeTabs.sumLeft[i-1] + splitted[i].MaxLeft, mergeTabs.MaxLeft[i-1]); } for(int i = K-2; i >= 0; --i) { mergeTabs.sumRight[i] = mergeTabs.sumRight[i+1] + splitted[i].sum; mergeTabs.MaxRight[i] = max(mergeTabs.sumRight[i+1] + splitted[i].MaxRight, mergeTabs.MaxRight[i+1]); } mergeTabs.MaxBoth[0] = splitted[0].MaxBoth + mergeTabs.sumRight[1]; mergeTabs.MaxBoth[K-1] = mergeTabs.sumLeft[K-2] + splitted[K-1].MaxBoth; for(int i = 1; i < K-2; ++i) { mergeTabs.MaxBoth[i] = mergeTabs.sumLeft[i-1] + splitted[i].MaxBoth + mergeTabs.sumRight[i+1]; } /*printf("\nsumLeft = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.sumLeft[i]); printf("\nsumRight = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.sumRight[i]); printf("\nMaxLeft = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxLeft[i]); printf("\nMaxRight = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxRight[i]); printf("\nMaxBoth = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxBoth[i]); printf("\n\n");*/ LL result = 0; for(int i = 0; i < K-1; ++i) { result = max(result, mergeTabs.MaxLeft[i] + mergeTabs.MaxRight[i+1]); } for(int i = 0; i < K; ++i) { result = max(result, mergeTabs.MaxBoth[i]); } return result; } int main() { LL instances = NumberOfNodes(); LL all_length = GetN(); /*scanf("%lld %lld",&instances,&all_length); for(int i = 0; i < all_length; ++i) scanf("%lld", &tab[i]);*/ LL one_len = all_length/instances; one_len++; LL offs = 0; /*for(int i = 0; i < instances; ++i) { if( offs + one_len < all_length ) { calcBlock(offs, one_len); } else { calcBlock(offs, all_length-offs); } offs += one_len; }*/ if( MyNodeId() * (one_len+1) > all_length ) { calcBlock( MyNodeId() * one_len, all_length - MyNodeId() * one_len ); } else { calcBlock( MyNodeId() * one_len, one_len ); } if ( MyNodeId() == 0 ) { for(int i = 0; i < instances; ++i) { Receive(i); splitted[i].sum = GetLL(i); //Receive(i); splitted[i].MaxLeft = GetLL(i); //Receive(i); splitted[i].MaxRight = GetLL(i); //Receive(i); splitted[i].MaxBoth = GetLL(i); } printf("%lld\n", merge(instances)); } }
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 | #include <algorithm> #include <cstdio> #include "kanapka.h" #include "message.h" using namespace std; typedef long long LL; struct BlockDesc { LL sum; LL MaxLeft; LL MaxRight; LL MaxBoth; }; void print(BlockDesc * block) { printf("sum = %lld, MaxLeft = %lld, MaxRight = %lld, MaxBoth = %lld\n", block->sum, block->MaxLeft, block->MaxRight, block->MaxBoth); } int M; #define MAX_LEN 100 LL tab[MAX_LEN]; struct BlockCalcs { LL sumLeft[MAX_LEN]; LL sumRight[MAX_LEN]; LL MaxLeft[MAX_LEN]; LL MaxRight[MAX_LEN]; LL MaxBoth[MAX_LEN]; }; BlockCalcs block; #define MAX_INSTANCES 101 BlockDesc splitted[MAX_INSTANCES]; int InstCounter = 0; LL GetVal(LL n, LL offset) { //return tab[offset+n]; return (GetTaste(offset+n)); } void calcBlock(LL offset, LL length) { int M = length; BlockDesc res; if( M > 1 ) { /*printf("tab: "); for(int i = 0; i < M; ++i) printf("%lld ", GetVal(i, offset));*/ block.sumLeft[0] = GetVal(0, offset); block.sumRight[M-1] = GetVal(M-1, offset); block.MaxLeft[0] = max(GetVal(0, offset), 0LL); block.MaxRight[M-1] = max(GetVal(M-1, offset), 0LL); for(int i = 1; i < M; ++i) { block.sumLeft[i] = block.sumLeft[i-1] + GetVal(i, offset); block.MaxLeft[i] = max(block.sumLeft[i], block.MaxLeft[i-1]); } for(int i = M-2; i >= 0; --i) { block.sumRight[i] = block.sumRight[i+1] + GetVal(i, offset); block.MaxRight[i] = max(block.sumRight[i], block.MaxRight[i+1]); } for(int i = 0; i < M-1; ++i) { block.MaxBoth[i] = block.MaxLeft[i] + block.MaxRight[i+1]; } res.sum = block.sumLeft[M-1]; res.MaxLeft = block.MaxLeft[0]; res.MaxRight = block.MaxRight[0]; res.MaxBoth = block.MaxBoth[0]; for(int i = 1; i < M-1; ++i) { res.MaxLeft = max(res.MaxLeft, block.MaxLeft[i]); res.MaxRight = max(res.MaxRight, block.MaxRight[i]); res.MaxBoth = max(res.MaxBoth, block.MaxBoth[i]); } } else { res.sum = GetVal(0, offset); res.MaxLeft = max(0LL, GetVal(0, offset)); res.MaxRight = res.MaxLeft; res.MaxBoth = res.MaxRight; } //splitted[InstCounter++] = res; PutLL(0, res.sum); PutLL(0, res.MaxLeft); PutLL(0, res.MaxRight); PutLL(0, res.MaxBoth); Send(0); /*printf("\nsumLeft = "); for(int i = 0; i < M; ++i) printf("%lld ", block.sumLeft[i]); printf("\nsumRight = "); for(int i = 0; i < M; ++i) printf("%lld ", block.sumRight[i]); printf("\nMaxLeft = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxLeft[i]); printf("\nMaxRight = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxRight[i]); printf("\nMaxBoth = "); for(int i = 0; i < M; ++i) printf("%lld ", block.MaxBoth[i]); printf("\n\n");*/ } struct MergeCalcs { LL sumLeft[MAX_INSTANCES]; LL sumRight[MAX_INSTANCES]; LL MaxLeft[MAX_INSTANCES]; LL MaxRight[MAX_INSTANCES]; LL MaxBoth[MAX_INSTANCES]; }; MergeCalcs mergeTabs; LL merge(LL instances) { int K = instances; /*for(int i = 0; i < K; ++i) { print(splitted + i); }*/ MergeCalcs res; mergeTabs.sumLeft[0] = splitted[0].sum; mergeTabs.sumRight[K-1] = splitted[K-1].sum; mergeTabs.MaxLeft[0] = splitted[0].MaxLeft; mergeTabs.MaxRight[K-1] = splitted[K-1].MaxRight; for(int i = 1; i < K; ++i) { mergeTabs.sumLeft[i] = mergeTabs.sumLeft[i-1] + splitted[i].sum; mergeTabs.MaxLeft[i] = max(mergeTabs.sumLeft[i-1] + splitted[i].MaxLeft, mergeTabs.MaxLeft[i-1]); } for(int i = K-2; i >= 0; --i) { mergeTabs.sumRight[i] = mergeTabs.sumRight[i+1] + splitted[i].sum; mergeTabs.MaxRight[i] = max(mergeTabs.sumRight[i+1] + splitted[i].MaxRight, mergeTabs.MaxRight[i+1]); } mergeTabs.MaxBoth[0] = splitted[0].MaxBoth + mergeTabs.sumRight[1]; mergeTabs.MaxBoth[K-1] = mergeTabs.sumLeft[K-2] + splitted[K-1].MaxBoth; for(int i = 1; i < K-2; ++i) { mergeTabs.MaxBoth[i] = mergeTabs.sumLeft[i-1] + splitted[i].MaxBoth + mergeTabs.sumRight[i+1]; } /*printf("\nsumLeft = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.sumLeft[i]); printf("\nsumRight = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.sumRight[i]); printf("\nMaxLeft = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxLeft[i]); printf("\nMaxRight = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxRight[i]); printf("\nMaxBoth = "); for(int i = 0; i < K; ++i) printf("%lld ", mergeTabs.MaxBoth[i]); printf("\n\n");*/ LL result = 0; for(int i = 0; i < K-1; ++i) { result = max(result, mergeTabs.MaxLeft[i] + mergeTabs.MaxRight[i+1]); } for(int i = 0; i < K; ++i) { result = max(result, mergeTabs.MaxBoth[i]); } return result; } int main() { LL instances = NumberOfNodes(); LL all_length = GetN(); /*scanf("%lld %lld",&instances,&all_length); for(int i = 0; i < all_length; ++i) scanf("%lld", &tab[i]);*/ LL one_len = all_length/instances; one_len++; LL offs = 0; /*for(int i = 0; i < instances; ++i) { if( offs + one_len < all_length ) { calcBlock(offs, one_len); } else { calcBlock(offs, all_length-offs); } offs += one_len; }*/ if( MyNodeId() * (one_len+1) > all_length ) { calcBlock( MyNodeId() * one_len, all_length - MyNodeId() * one_len ); } else { calcBlock( MyNodeId() * one_len, one_len ); } if ( MyNodeId() == 0 ) { for(int i = 0; i < instances; ++i) { Receive(i); splitted[i].sum = GetLL(i); //Receive(i); splitted[i].MaxLeft = GetLL(i); //Receive(i); splitted[i].MaxRight = GetLL(i); //Receive(i); splitted[i].MaxBoth = GetLL(i); } printf("%lld\n", merge(instances)); } } |