LG10444
首先有一个显然的结论,即若可以分成超过 \(2\) 个序列,则一定可以分成 \(2\) 个序列。如样例中的第二组数据,可以直接分成 \(\{1,1,1,9 \}\) 和 \(\{8,0\}\)。严谨证明留给读者思考。
有了上面这个结论后,就转化为判断是否能够分成两个序列。注意到极差只与最大值与最小值有关,因此全局最大值和最小值是一定会影响极差的。换句话说,极差的其中一个变量已经确定下来了,就可以通过枚举另一个变量来确定这个极差了。
记全局最小值为 \(\min\),最大值为 \(\max\)。我们考虑最小值所在序列的情况。假设该序列的最大值为 \(x\),则极差 \(c=x-\min\),最大值所在序列的最小值为 \(\max-c = \max - x + \min\)。枚举每一个 \(a_i\) 作为 \(x\),判断所求得的值是否在 \(a\) 中即可。
有一种情况需要特别注意,即 \(x\) 和求出的值相等,此时需要特判是否出现至少 \(2\) 次。另外,\(\min\) 与 \(\max\) 用来求极差时要特殊处理,具体见代码。
由于使用了 map 记录出现次数,因此总时间复杂度为 \(O(Tn\log n)\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[1000001],flag,mi,mx;
map<int,int> mp;
signed main()
{
int T,id;
cin >> T >> id;
while( T -- )
{
flag = 0;
mp.clear();
cin >> n;
cin >> a[1],mp[a[1]] ++;
mi = mx = a[1];
for( int i = 2 ; i <= n ; i ++ )
cin >> a[i],mp[a[i]] ++,mx = max( mx , a[i] ),mi = min( mi , a[i] );
for( int i = 1 ; i <= n ; i ++ )
if( mp[mx - a[i] + mi] && a[i] != mi && a[i] != mx )
{
if( a[i] == mx - a[i] + mi && mp[a[i]] == 1 ) continue;
flag = 1;
break;
}
if( mp[mi] > 1 && mp[mx] > 1 )
flag = 1;
if( flag ) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
还是菜。