import java.util.HashMap; import java.util.Map; public class SolutionFlagpoles { public static void main(String[] args) { new SolutionFlagpoles().run(); } int myId = message.MyNodeId(); int nodeCount = message.NumberOfNodes(); long itemCount = flagpoles.GetNumFlagpoles(); long perNode = itemCount / (nodeCount - 1) + 1; long iL = Math.min((myId - 1) * perNode, itemCount); long iR = Math.min(myId * perNode, itemCount); void run() { if (myId == 0) { server(); } else { client(); } } static class Sequence { long d; long length; long startIndex; long startElement; long endElement; public Sequence(long d, long length, long startIndex, long startElement, long endElement) { this.d = d; this.length = length; this.startIndex = startIndex; this.startElement = startElement; this.endElement = endElement; } static Sequence zero(long startIndex) { return new Sequence(0, 0, startIndex, -1, -1); } long endIndex() { return Math.max(startIndex, startIndex + length - 1); } Sequence addElementRight(long element) { if (endElement == -1) { return new Sequence(0, 1, startIndex, element, element); } if (length == 1) { return new Sequence(element - startElement, 2, startIndex, startElement, element); } if (element - endElement == d) { return new Sequence(d, length + 1, startIndex, startElement, element); } return new Sequence(element - endElement, 2, startIndex + length - 1, endElement, element); } Sequence addSequenceRight(Sequence o) { if (endIndex() + 1 != o.startIndex) { return o; } if (o.length == 1) { return addElementRight(o.startElement); } if (d != o.d) { if (o.startElement - endElement == o.d) { return new Sequence(o.d, o.length + 1, o.startIndex - 1, endElement, o.endElement); } return o; } if (o.startElement - endElement != d) { return o; } return new Sequence(d, length + o.length, startIndex, startElement, o.endElement); } boolean isBetter(Sequence o) { return length > o.length; } void send(int target) { message.PutLL(target, d); message.PutLL(target, length); message.PutLL(target, startIndex); message.PutLL(target, startElement); message.PutLL(target, endElement); message.Send(target); } static Sequence receive(int source) { message.Receive(source); return new Sequence(message.GetLL(source), message.GetLL(source), message.GetLL(source), message.GetLL(source), message.GetLL(source)); } public String toString() { return "{" + d + " " + length + " " + startIndex + " " + startElement + " " + endElement + "}"; } } void client() { Map map = new HashMap<>(); for (long i = iL; i < iR; i++) { map.put(i, flagpoles.GetHeight(i)); } Sequence best = Sequence.zero(iL); Sequence current = Sequence.zero(iL); Sequence leftmost = Sequence.zero(iL); for (long i = iL; i < iR; i++) { current = current.addElementRight(map.get(i)); if (current.startIndex == iL) { leftmost = current; } if (current.isBetter(best)) { best = current; } } leftmost.send(0); current.send(0); best.send(0); } void server() { Sequence best = Sequence.zero(0); Sequence current = Sequence.zero(0); for (int clientId = 1; clientId < nodeCount; clientId++) { Sequence clientLeftmost = Sequence.receive(clientId); Sequence clientRightmost = Sequence.receive(clientId); Sequence clientBest = Sequence.receive(clientId); // System.out.println(clientId + " -> " + clientLeftmost.toString()); // System.out.println(clientId + " -> " + clientBest.toString()); if (clientBest.isBetter(best)) { best = clientBest; } current = current.addSequenceRight(clientLeftmost); // System.out.println(current.toString()); if (current.isBetter(best)) { best = current; } if (clientRightmost.endIndex() > current.endIndex()) { current = clientRightmost; } } System.out.println(best.length); } }