AI秒杀?【测试AI】
原题链接:34572.划分区间2025-05-02 21:04:20
发布于:浙江
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll NEG_INF = LLONG_MIN / 2;
struct Fenwick {
    int n;
    vector<ll> t;
    Fenwick(int _n): n(_n), t(n+1, NEG_INF) {}
    // 在位置 i 上更新:t[i] = max(t[i], v)
    void update(int i, ll v) {
        for (; i <= n; i += i & -i)
            t[i] = max(t[i], v);
    }
    // 查询前缀 [1..i] 的最大值
    ll query(int i) {
        ll r = NEG_INF;
        for (; i > 0; i -= i & -i)
            r = max(r, t[i]);
        return r;
    }
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<ll> A(n+1, 0);
    for(int i = 1; i <= n; i++){
        cin >> A[i];
    }
    // 1) 计算前缀和
    vector<ll> S(n+1, 0);
    for(int i = 1; i <= n; i++){
        S[i] = S[i-1] + A[i];
    }
    // 2) 离散化所有前缀和
    vector<ll> comp = S;
    sort(comp.begin(), comp.end());
    comp.erase(unique(comp.begin(), comp.end()), comp.end());
    int m = comp.size();
    // 3) 准备两个 Fenwick Tree:
    //    FT1 存 dp[j] - j,用于查询 s[j] < s[i] 的情况
    //    FT2 存 dp[j] + j,用于查询 s[j] > s[i] 的情况(反向离散后用前缀即可)
    Fenwick ft1(m), ft2(m);
    // 4) 存储相等前缀和时的最佳 dp 值
    vector<ll> best_eq(m+1, NEG_INF);
    auto get_id = [&](ll x){
        return int(lower_bound(comp.begin(), comp.end(), x) - comp.begin()) + 1;
    };
    vector<ll> dp(n+1, NEG_INF);
    dp[0] = 0;
    // 初始化 j=0 的状态
    int id0 = get_id(S[0]);
    best_eq[id0] = 0;
    ft1.update(id0, dp[0] - 0);
    // 对于 ft2,我们把离散坐标反过来:rev = m-id+1
    ft2.update(m - id0 + 1, dp[0] + 0);
    // 5) 按顺序计算 dp[i]
    for(int i = 1; i <= n; i++){
        int id = get_id(S[i]);
        // 情况1:存在 j<i 且 s[j] < s[i]
        ll v1 = ft1.query(id - 1);
        if (v1 > NEG_INF) v1 += i;
        // 情况2:存在 j<i 且 s[j] > s[i]
        ll v2 = ft2.query(m - (id + 1) + 1);
        if (v2 > NEG_INF) v2 -= i;
        
        // 情况3:存在 j<i 且 s[j] == s[i]
        ll v3 = best_eq[id];
        
        dp[i] = max({v1, v2, v3});
        // 更新三种结构
        best_eq[id] = max(best_eq[id], dp[i]);
        ft1.update(id, dp[i] - i);
        ft2.update(m - id + 1, dp[i] + i);
    }
    // 答案就是 dp[n]
    cout << dp[n] << "\n";
    return 0;
}
全部评论 2
除了题面没有说其他的信息?
2025-05-02 来自 广东
0顶!
2025-05-02 来自 浙江
0















有帮助,赞一个