学习绝对值C++算法

  • Post author:
  • Post category:其他


区间最大值和最小值的绝对值相等,有以下两种情况:

第一种情况:区间中只有同一种数字。这个比较简单,通过简单的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;

}



版权声明:本文为xdpcxq原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。