@atcoder - ARC066F@ Contest with Drinks Hard


@description@

Given sequence T1, T2, ... TN, you can choose from a number of Ti, 0 can be selected (i.e., not selected).

(Number satisfying T [L ... R] are selected interval [L, R]) of the right you choose a defined value = - (Ti sum of your choice), you want the weight as large as possible.

There are M times asked Always ask if the T [Pi] modified to Xi, the maximum weight you can select.

The Constraints
. 1 <= N, M <= 5,1. 3 * ^ 10 <= of Ti <= 10 ^. 9 and the sum of all Ti <= 10 ^ 12.
For each query, satisfies 1 <= Pi <= N, 1 <= Xi <= 10 ^ 9.

Input
Input following form:
N
Tl T2 ... the TN
M
Pl the X1
P2 an X2
:
the PM XM

Output
For each inquiry, the output of the answers.

Sample Input 1
5
1 1 4 1 1
2
3 2
3 10
Sample Output 1
9
2

@solution@

Consider modifying T [Pi] after Xi, the last option to either contain or not contain Pi.
If it does not, you only need 1 ... Pi - 1 Select and Pi + 1 ... N the maximum value obtained.
If contained, we need to pre-treatment comprising the Pi optimal solution, then the optimal solution + T [Pi] - Xi.

In summary, we need to deal with the three things: the first f [i] represents from 1 ... i select the optimal answer, the second g [i] indicating the selection of the most from i ... N excellent answer, the third H [i] denotes the i must choose the best answer.

Considering a first step, let's think f [i]. I do not either choose from f [i-1] transferred from; or select i, j we mean that we enumerate a forced choice i + 1 ... number j in all, the contribution to the f [j] + ([i + 1, the number of interval j] in) - ([i + 1, T value j] and).
And by pre-treating the prefix S [i] = T [1 ] + T [2] + ... T [i], may be transferred to write more specific formula:
\ [F [I] = \ max (F [ i-1], \ max_ { 0 \ le j <i} (f [j] + S [j] - S [i] + \ frac {(ij + 1) * (ij)} {2}) ) \]

Optimized slope above the transfer very little to change that equation can indeed find the slope optimization. Here it is not specifically written.
In conclusion, this formula is a monotonically increasing slope and a monotonically increasing slope abscissa optimization can be done monotonically stack time complexity O (n) a.
And g [i] can be similarly processed. Here is not specifically talk about it.

Now consider how demand h [i]. The method of enumeration is most violent left left point i a l, i to the right of a right end point enumeration r, contribution interval [l, r] is calculated plus f [l - 1] + g [r + 1].
Consider optimization, we found very appropriate partition cdq(In fact, I do not know that it should not be called cdq divide and conquer, but feels more like)

For the interval [left, right], set midpoint of its mid, we consider only satisfies left <= l <= mid < r <= right interval [l, r] contribution of h [l ... r] of .
Then the recursion [left, mid] and [mid + 1, right], continue processing sub issue until left = right.

How to deal with it? We first [left, mid] was added monotone point stack; and sweep from left to right [mid + 1, right] is obtained by optimizing the slope of all points [mid + 1, right] the right point as the answer; then from right to left scanning, while maintaining a maximum sweep x [x, right] of tmp, tmp with the updated h [x].
Then in turn [mid + 1, right] was added monotone stack, update [left, mid] value of h. This process is similar to the above, not repeat them.

@accepted code@

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 300000;
const ll INF = (1LL<<60);
ll f[MAXN + 5], g[MAXN + 5], h[MAXN + 5];
ll S[MAXN + 5], T[MAXN + 5];
ll fk(int i) {return i;}
ll fx(int j) {return 2LL*j;}
ll fc(int i) {return 1LL*i*i + i - 2*S[i];}
ll fy(int j) {return 2*S[j] + f[j] - j + 1LL*j*j;}
double fslope(int p, int q) {return 1.0*(fy(q) - fy(p)) / (fx(q) - fx(p));}
ll gk(int i) {return -i;}
ll gx(int j) {return -2LL*j;}
ll gc(int i) {return 1LL*i*i - i + 2*S[i-1];}
ll gy(int j) {return -2*S[j-1] + g[j] + j + 1LL*j*j;}
double gslope(int p, int q) {return 1.0*(gy(q) - gy(p)) / (gx(q) - gx(p));}
int stk[MAXN + 5], tp;
int N, M;
void get_dp() {
    f[0] = 0; stk[tp = 1] = 0;
    for(int i=1;i<=N;i++) {
        while( tp > 1 && fk(i) >= fslope(stk[tp], stk[tp-1]) )
            tp--;
        f[i] = max(f[i - 1], fc(i) - fk(i)*fx(stk[tp]) + fy(stk[tp]));
        while( tp > 1 && fslope(i, stk[tp]) >= fslope(stk[tp], stk[tp-1]) )
            tp--;
        stk[++tp] = i;
    }
    g[N + 1] = 0; stk[tp = 1] = N + 1;
    for(int i=N;i>=1;i--) {
        while( tp > 1 && gk(i) >= gslope(stk[tp], stk[tp-1]) )
            tp--;
        g[i] = max(g[i + 1], gc(i) - gk(i)*gx(stk[tp]) + gy(stk[tp]));
        while( tp > 1 && gslope(i, stk[tp]) >= gslope(stk[tp], stk[tp-1]) )
            tp--;
        stk[++tp] = i;
    }
}
ll tmp[MAXN + 5];
void divide_conquer(int l, int r) {
    if( l == r ) {
        h[l] = f[l + 1] - 2*T[l] + g[r + 1] + 2;
        return ;
    }
    int mid = (l + r) >> 1;
    divide_conquer(l, mid);
    divide_conquer(mid + 1, r);
    stk[tp = 1] = l - 1;
    for(int i=l;i<mid;i++) {
        while( tp > 1 && fk(i) >= fslope(stk[tp], stk[tp-1]) )
            tp--;
        while( tp > 1 && fslope(i, stk[tp]) >= fslope(stk[tp], stk[tp-1]) )
            tp--;
        stk[++tp] = i;
    }
    for(int i=mid+1;i<=r;i++) {
        while( tp > 1 && fk(i) >= fslope(stk[tp], stk[tp-1]) )
            tp--;
        tmp[i] = fc(i) - fk(i)*fx(stk[tp]) + fy(stk[tp]) + g[i + 1];
    }
    ll p = -INF;
    for(int i=r;i>mid;i--) {
        p = max(p, tmp[i]);
        h[i] = max(h[i], p);
    }
    stk[tp = 1] = r + 1;
    for(int i=r;i>mid+1;i--) {
        while( tp > 1 && gk(i) >= gslope(stk[tp], stk[tp-1]) )
            tp--;
        while( tp > 1 && gslope(i, stk[tp]) >= gslope(stk[tp], stk[tp-1]) )
            tp--;
        stk[++tp] = i;
    }
    for(int i=mid;i>=l;i--) {
        while( tp > 1 && gk(i) >= gslope(stk[tp], stk[tp-1]) )
            tp--;
        tmp[i] = gc(i) - gk(i)*gx(stk[tp]) + gy(stk[tp]) + f[i - 1];
    }
    p = -INF;
    for(int i=l;i<=mid;i++) {
        p = max(p, tmp[i]);
        h[i] = max(h[i], p);
    }
}
int main() {
    scanf("%d", &N);
    for(int i=1;i<=N;i++)
        scanf("%lld", &T[i]), S[i] = S[i - 1] + T[i];
    get_dp(), divide_conquer(1, N);
    scanf("%d", &M);
    for(int i=1;i<=M;i++) {
        int P, X; scanf("%d%d", &P, &X);
        printf("%lld\n", max(f[P-1] + g[P+1], h[P] + 2*T[P] - 2*X)/2);
    }
}

@details@

h [i] is the value of i must be included, it may be negative, it should be assigned to h -inf when initialized.

Now do not atcoder saying the ARC, ARC has become the era of tears. . .

Guess you like

Origin www.cnblogs.com/Tiw-Air-OAO/p/11407452.html