KAGAIN - Chiến trường Ô qua

Tags: stack, dp

Problem

https://vn.spoj.com/problems/KAGAIN

https://oj.vnoi.info/problem/KAGAIN

Lại nói về Lục Vân Tiên , sau khi vượt qua vòng loại để trở thành Tráng Sỹ , anh đã gặp được Đôrêmon và được chú mèo máy cho đi quá giang về thế kỷ 19 . Trở lại quê hương sau nhiều năm xa cách , với tấm bằng Tráng Sỹ hạng 1 do Liên Đoàn Type Thuật cấp , anh đã được Đức Vua cử làm đại tướng thống lãnh 3 quân chống lại giặc Ô Qua xâm lăng . Đoàn quân của anh sẽ gồm N đại đội , đại đội i có A[i] ( > 0 ) người . Quân sỹ trong 1 đại đội sẽ đứng thành 1 cột từ người 1 -> người A[i] , như vậy binh sỹ sẽ đứng thành N cột . Vì Vân Tiên quyết 1 trận sẽ đánh bại quân Ô Qua nên đã cử ra 1 quân đoàn hùng mạnh nhất . Trong sử cũ chép rằng , quân đoàn của Vân Tiên cử ra lúc đó là một nhóm các đại đội có chỉ số liên tiếp nhau ( tức là đại đội i , i + 1 , … j ) . Vì sử sách thì mối mọt hết cả nên chỉ biết được mỗi thế . Ngoài ra theo giang hồ đồn đại thì sức mạnh của 1 quân đoàn = số người của đại đội ít người nhất * số đại đội được chọn . Nhiệm vụ của bạn là dựa trên các thông số của các nhà khảo cổ có được , hãy cho biết quân đoàn mà Vân Tiên đã chọn ra là từ đại đội nào đến đại đội nào . Chú ý nếu có nhiều phương án thì ghi ra phương án mà chỉ số của đại đội đầu tiên được chọn là nhỏ nhất .

Bài này O(N) mới thực sự coi là accept . Còn lại O(NlogN) , O(N^2) thì đó là do bạn may mắn accept thôi.#### Input

  • Dòng 1 : Số T là số bộ test .
  • T nhóm dòng tiếp theo , mỗi nhóm dòng mô tả 1 bộ test. Nhóm dòng thứ i:
    • Dòng 1: N ( <= 30000 )
    • Dòng 2: N số nguyên mô tả N số A[1] , A[2] , … A[N] ( các số nguyên dương <= 30000 ).

Output

Kết quả mỗi test ghi ra trên 1 dòng , gồm 3 số : sức mạnh quân đoàn mạnh nhất , chỉ số của đại đội đầu tiên và chỉ số của đại đội cuối cùng được chọn .

Example

Input
2
4
3 4 3 1
4
1 2 1 3

Output
9 1 3
4 1 4

Tutorial


Submission

KAGAIN.cpp
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;
typedef unsigned long long ull;

#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define ep emplace_back
#define EL printf("\n")
#define sz(A) (int) A.size()
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define FOD(i,r,l) for (int i=r;i>=l;i--)
#define fillchar(a,x) memset(a, x, sizeof (a))
#define faster ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

const int N = 30005;
int T, n, a[N], L[N], R[N];
stack<int> st;

int main() {
//  freopen("INP.TXT", "r", stdin);
//  freopen("OUT.TXT", "w", stdout);

	cin >> T;
	while (T--) {
		scanf("%d", &n);
		FOR(i,1,n) scanf("%d", &a[i]);

		stack<int> st;
		FOR(i,1,n) {
			while (! st.empty() && a[i] <= a[st.top()]) st.pop();
			L[i] = st.empty() ? 1 : st.top() + 1;
			st.push(i);
		}

		st = stack<int> {};
		FOD(i,n,1) {
			while (! st.empty() && a[i] <= a[st.top()]) st.pop();
			R[i] = st.empty() ? n : st.top() - 1;
			st.push(i);
		}

		int ans = 0, i = 0, j = 0;
		FOR(k,1,n)
		if (ans < (R[k] - L[k] + 1 ) * a[k])
			ans = (R[k] - L[k] + 1 ) * a[k], i = L[k], j = R[k];

		printf("%d %d %d\n", ans, i, j);
	}

	return 0;
}