学习绝对值C++算法

区间最大值和最小值的绝对值相等,有以下两种情况:
第一种情况:区间中只有同一种数字。这个比较简单,通过简单的for循环向后计数得到。
第二种情况:区间中最大值和最小值为相反数。
第二种情况具体来说,就是最大值1,最小值-1,和最大值2,最小值-2。
考虑如何求解第二种情况。

考虑固定左端点时,如何找合法的右端点:
1. 对于最大值为1最小值-1的情况:右端点需要保证:区间中有1和-1,区间中没有2和-2。这可以通
过维护左端点向后的1/-1/2/-2的初始位置找到。右端点的起始位置为max(下一个1的位置,下一
个-1的位置),结束位置为min(下一个2的位置,下一个-2的位置)
2. 对于最大值为2最小值-2的情况:右端点需要保证:区间中有2和-2。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 5e5 + 10;
const int inf = 0x3f3f3f3f;
ll n, ans, num[maxn];
int nxt[maxn][5];
int startpos, endpos;
// -2 --> 0 // -1 --> 1
// 1 --> 3  // 2 --> 4
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n;
    memset(nxt, 0x3f, sizeof nxt);
    for(int i = 1;i <= n; ++i) {
        cin >> num[i];
    }
    ll ret = 1, lst = num[1];
    for(int i = 2;i <= n; ++i) {
        if(num[i] == lst) ++ret;
        else {
            ans += ret * (ret + 1) / 2;
            ret = 1; lst = num[i];
        }
    }
    ans += ret * (ret + 1) / 2;
    for(int i = n;i >= 1; --i) {
        for(int j = 0;j <= 4; ++j) nxt[i][j] = nxt[i + 1][j];
        nxt[i][num[i] + 2] = i;
        int maxpos1 = nxt[i][1 + 2], maxpos2 = nxt[i][2 + 2];
        int minpos1 = nxt[i][-1 + 2], minpos2 = nxt[i][-2 + 2];
        startpos = max(maxpos2, minpos2); endpos = n + 1;
        if(startpos != inf && startpos < endpos) ans += endpos - startpos;
        startpos = max(maxpos1, minpos1); endpos = min(min(maxpos2, minpos2), (int)n + 1);
        if(startpos != inf && startpos < endpos) ans += endpos - startpos;
    }
    cout << ans << '\n';
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值