Cod sursa(job #1543199)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 6 decembrie 2015 01:28:04
Problema Subsecventa de suma maxima Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <cstring>
#include <cctype>
using namespace std;

#ifdef INFOARENA
#define ProblemName "ssm"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif

template <class T> void readNum(T &nr) {
	nr = 0;
	T sign = 1;
	char c;
	while (!isdigit(c = getchar()))
		(c == '-') && (sign = -1);
	do {
		nr = nr * 10 + c - '0';
	} while (isdigit(c = getchar()));
	nr *= sign;
}

#define NMAX 6000010
int A[NMAX];

class ssm{
public:
	int left, right, sval;
	ssm() {}
	ssm(int L, int R, int S) : left(L), right(R), sval(S) {}
	bool operator > (ssm& other) {
		return (this->sval > other.sval);
	}
	bool operator >= (ssm& other) {
		return (this->sval >= other.sval);
	}
	bool operator == (ssm& other) {
		return (this->sval == other.sval);
	}
};

ssm crossm(int low, int high, int crosspoint) {
	int lmax = 0;
	int lindex = crosspoint;
	int index = crosspoint;
	int csum = 0;
	while (index > low) {
		index--;
		csum += A[index];
		if (csum > lmax) {
			lmax = csum;
			lindex = index;
		}
	}
	index = crosspoint;
	csum = 0;
	int rmax = 0;
	int rindex = crosspoint;
	while (index < high) {
		index++;
		csum += A[index];
		if (csum > rmax) {
			rmax = csum;
			rindex = index;
		}
	}
	return ssm(lindex, rindex, lmax + A[crosspoint] + rmax);
}

ssm solvessm(int low, int high) {
	if (low == high)
		return ssm(low, high, A[low]);
	int mid = (low + high) >> 1;
	ssm sleft = solvessm(low, mid);
	ssm sright = solvessm(mid + 1, high);
	ssm scross = crossm(low, high, mid);
	if (sleft >= sright) {
		if (sleft > scross)
			return sleft;
		if (sleft == scross && sleft.left <= scross.left)
			return sleft;
		return scross;
	}
	if (scross >= sright)
		return scross;
	return sright;
}

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OuFile, "w", stdout));
	int N;
	readNum(N);
	for (int i = 0; i < N; i++)
		readNum(A[i]);
	ssm sol = solvessm(0, N - 1);
	printf("%d %d %d\n", sol.sval, sol.left + 1, sol.right + 1);
	return 0;
}