Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- // #define DEBUG
- // #define ABOBA
- #define mins_t ll
- typedef long long ll;
- const ll INF = 1000000001;
- // typedef struct {
- // ll first, second;
- // } mins_t;
- ll min(ll a, ll b) {
- return a < b ? a : b;
- }
- ll max(ll a, ll b) {
- return a > b ? a : b;
- }
- ll n;
- ll *a, *max_step;
- mins_t **table;
- mins_t fetch(mins_t a, mins_t b) {
- /*mins_t ans;
- if (a.first < b.first) {
- ans.first = a.first;
- ans.second = min(a.second, b.first);
- } else {
- ans.first = b.first;
- ans.second = min(b.second, a.first);
- }
- return ans;*/
- return min(a, b);
- }
- mins_t get_mins(ll l, ll r) {
- #ifndef ABOBA
- if (l > r) {
- return (mins_t){INF, INF};
- }
- ll j = max_step[r-l+1];
- return fetch(table[r][j], table[l+(1<<j) - 1][j]);
- #else
- if (l > n-1 || l < 0 || r < 0 || r > n-1 || l > r) {
- return (mins_t){INF, INF};
- }
- ll ans = a[l];
- for (ll i=l+1; i<r+1; ++ i) {
- ans = min(ans, a[i]);
- }
- return ans;
- #endif
- }
- int main(void) {
- scanf("%lld", &n);
- a = (ll*) malloc (sizeof(ll) * n);
- for (ll i=0; i<n; ++ i) {
- scanf("%lld", &a[i]);
- }
- ll m = 21;
- table = (mins_t**) malloc(sizeof(mins_t*) * n);
- for (ll i=0; i<n; ++ i) {
- table[i] = (mins_t*)malloc(sizeof(mins_t) * m);
- }
- for (ll i=0; i<n; ++ i) {
- table[i][0] = a[i];
- }
- for (ll j=1; j<m; ++ j) {
- for (ll i=0; i<n; ++ i) {
- if ((i - (1 << (j-1))) > -1) {
- table[i][j] = fetch(table[i][j-1], table[i-(1<<(j-1))][j-1]);
- } else {
- table[i][j] = table[i][j-1];
- }
- }
- }
- max_step = (ll*) malloc(sizeof(ll) * (n+1));
- max_step[0] = 0;
- for (ll i=1; i<=n; ++ i) {
- max_step[i] = max_step[i-1];
- if ((1 << (max_step[i] + 1)) <= i) {
- ++ max_step[i];
- }
- }
- #ifdef DEBUG
- for (ll i=0; i<n; ++ i) {
- for (ll j=i; j<n; ++ j) {
- mins_t tmp = get_mins(i, j);
- printf("[DEBUG] %lld, %lld: %lld\n", i, j, tmp);
- }
- }
- #endif
- ll ans = 0;
- for (ll i=0; i<n; ++ i) {
- ll l = i, r = i;
- ll L, R, M;
- L = 0, R = i;
- while(L<R) {
- M = (L+R) >> 1;
- if (get_mins(M, i) == a[i]) {
- R = M;
- } else {
- L = M + 1;
- }
- }
- l = R;
- L = i, R = n-1;
- while(L<R) {
- M = (L+R+1) >> 1;
- if (get_mins(i, M) == a[i]) {
- L = M;
- } else {
- R = M - 1;
- }
- }
- r = L;
- if (r > l) {
- ll nmin = INF;
- if (i > l) {
- nmin = get_mins(l, i-1);
- }
- if (i < r) {
- nmin = min(nmin, get_mins(i+1, r));
- }
- ans = max(ans, (r-l+1) * (a[i] + nmin));
- }
- if (l > 0) {
- ll l1 = l - 1;
- if (l1 > 0 && a[l1-1] >= a[i]) {
- L = 0, R = l1-1;
- while(L<R) {
- M = (L+R) >> 1;
- if (get_mins(M, l1-1) >= a[i]) {
- R = M;
- } else {
- L = M + 1;
- }
- }
- l = R;
- }
- ans = max(ans, (r-l+1) * (a[i] + a[l1]));
- l = l1 + 1;
- }
- if (r < n-1) {
- ll r1 = r + 1;
- if (r1 < n-1 && a[r1+1] >= a[i]) {
- L = r1 + 1, R = n-1;
- while(L<R) {
- M = (L+R+1) >> 1;
- if (get_mins(r1+1, M) >= a[i]) {
- L = M;
- } else {
- R = M - 1;
- }
- }
- r = L;
- }
- ans = max(ans, (r-l+1) * (a[i] + a[r1]));
- r = r1 - 1;
- }
- }
- printf("%lld\n", ans);
- free(a);
- free(max_step);
- for (ll i=0; i<n; ++ i) {
- free(table[i]);
- }
- free(table);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment