Codeforces Round #812 (Div. 2)
(🕊了好久呜呜呜~)
题目大意:对一个序列可以进行一次操作:选择两个索引 l , r ,对 l , r 范围内的数都减一,然后称f(a)为将所有数删为0所需要的次数,问对于a的所有排列b,是否满足f(a)<=f(b).
思路:可以把原数组变成差分数组,然后对于l,r范围内的数-1,就是对应差分数组的a[l]-1,a[r+1]+1,就是变成了左边的数-1,右边的数+1,然后需要的次数就为max(大于0的数,小于0的数)。然后对于a的全排列,需要次数的最小可能为sort排序之后的结果(升序降序都可以)。然后对比一下最小的,如果当前序列的次数小于等于最小的话,那么就满足条件,否则就输出NO。
最后记得还要开longlong
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
#include<cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include<vector>
#include<queue>
#include<map>
#define ll long long
using namespace std;
const int N=1000000+100;
int n ,m,h;
ll s[N],cnt[N];
int main()
{
int t ;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i =1;i<=n;i++){
cin>>s[i];
cnt[i]=s[i]-s[i-1];
}
ll l=0,r=0;
for(int i =1;i<=n;i++)
{
if(cnt[i]>0)
l+=cnt[i];
else
r+=abs(cnt[i]);
}
ll res=max(l,r);
sort(s+1,s+1+n);
l=0,r=0;
for(int i =1;i<=n;i++)
{
cnt[i]=s[i]-s[i-1];
if(cnt[i]>0)
l+=cnt[i];
else
r+=abs(cnt[i]);
}
if(res<=l+r)
cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}