Solution to a problem DTOJ # 4123. "2019 Winter Camp group to improve" the whole company

Welcome to My Luogu Space .


[Title] effect

Has a sequence, there are two values for each point \ (a [i] \) and \ (T [I] \) .

If you choose the first \ (i \) points will be given (a [i] * t [ i] \) \ contribution, but can not choose \ ((a [i] -t [i], a [i] + t [i]) \) other points within the range.

Asked greatest contribution that can be obtained.


【answer】

Segment tree optimization dp .

Readily occur offline, \ (DP \) : \
(DP [I] = max (DP [J] + A [I] * T [I]), \) \ (\ (T + J [J] ≦ I ) \ \ & \ & \ (IT [I] ≥j) \) ;

But this time the efficiency is very good, so consider this optimization \ (dp \) .

We found that for the current \ (i \) enumeration \ (j \) time is always from \ (1 \) to start the enumeration, take \ (dp [j], \ \ j∈ [1, \ it [i ]] \) maximum.

Think of can query the maximum interval, a single point to modify the data structures.

But not within the range can take all the points that must also meet \ (T + J [J] ≦ I \) .

We also found that only the left side of this equation with \ (j \) , whereas our \ (i \) is an enumeration of the order, that is to say if the current \ (i \) can be taken to a certain \ ( J \) , then after the \ (i \) is also able to take this \ (J \) .

Thus it is only necessary only need to calculate a new good \ (dp [j] \) in \ (i = j + t [ j] \) when placed in a data structure like.

Each interrogation to the above operations, then the query interval \ ([1, \ it [ i]] \) maximum value of the recording and answer.


[Code]

// output format !!
// long long !!
#include <bits/stdc++.h>
#define H puts("HYX")
#define ls (x<<1)
#define rs (x<<1|1)
using std::max;
typedef long long LL;
const int MAXN = 1000000+10;
struct DATA{int loc; LL dat;};

int n, t[MAXN], a[MAXN];
LL tre[MAXN*4], ans;
std::vector<DATA> tmp[MAXN];

int rd(){
    char c;while(!isdigit(c=getchar()));
    int x=c-'0';while(isdigit(c=getchar())) x=x*10+c-'0';
    return x;
}
void modify(int x, int l, int r, int p, LL v){
    if(l == r) return tre[x] = v, void();
    int mid = (l+r)>>1;
    if(p <= mid) modify(ls, l, mid, p, v);
    else modify(rs, mid+1, r, p, v);
    tre[x] = max(tre[ls], tre[rs]);
}
LL query(int x, int l, int r, int ql, int qr){
    if(ql<=l && r<=qr) return tre[x];
    int mid = (l+r)>>1; LL res = 0;
    if(ql <= mid) res = max(res, query(ls, l, mid, ql, qr));
    if(qr > mid) res = max(res, query(rs, mid+1, r, ql, qr));
    return res;
}
int main(){
//  freopen("fc.in", "r", stdin);
//  freopen("fc.out", "w", stdout);
    scanf("%d", &n);
    for(int i=1; i<=n; ++i) t[i] = rd();
    for(int i=1; i<=n; ++i) a[i] = rd();
    for(int i=1; i<=n; ++i){
        for(auto j=tmp[i].begin(); j!=tmp[i].end(); ++j) 
            modify(1, 1, n, (*j).loc, (*j).dat);
        LL dp = (i-t[i]>0?query(1, 1, n, 1, i-t[i]):0)+1ll*a[i]*t[i];
        if(i+t[i] <= n) tmp[i+t[i]].push_back((DATA){i, dp});
        if(dp > ans) ans = dp;
    }
    printf("%lld", ans);
    return 0;
}

I remember long long !! within the function parameters because the burst of zero ......

Guess you like

Origin www.cnblogs.com/bosswnx/p/10988181.html
Recommended