题意:给一个长度为n的序列,问在 l 与 r 取不同值时最大值是多少
思路:枚举起点找后面某个点和他组成最大或最小值,multiset用值删除元素会将相同的元素一块删除。前缀和奇数位置找后面最大值,偶数位置找后面最小值。
ac代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
multiset<ll> ss;
ll a[maxn],b[maxn],sum[maxn],res=0;
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<n;i++) b[i]=abs(a[i]-a[i+1]),res=max(res,b[i]);
for(int i=1;i<n;i++) sum[i]=sum[i-1]+((i&1)?1:-1)*b[i],ss.insert(sum[i]);
for(int i=1;i<n;i++){
ll tmp;
if(i&1){//max
auto it=ss.end();
it--;
tmp=*(it);
tmp-=sum[i-1];
}
else{//min
tmp=*ss.begin();
tmp-=sum[i-1];
tmp=-tmp;
}
ss.erase(ss.find(sum[i]));//删除,是删除当前这个位置的元素
res=max(res,tmp);
}
printf("%lld\n",res);
return 0 ;
}