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;
}
posted @ 2024-05-18 17:32  liyilang2021  阅读(1)  评论(0编辑  收藏  举报