专栏文章

CF2171D 题解

CF2171D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min335wr
此快照首次捕获于
2025/12/01 19:46
3 个月前
此快照最后确认于
2025/12/01 19:46
3 个月前
查看原文
题目相当于判断:将所有满足 u<vu<vpu<pvp_u<p_vuuvv 连边,最后所有点是否在同一个连通块中。
我们把 p1pnp_1\sim p_n 分成两个部分 A,BA,B,一开始,AA 里面没有数,BB 里面有所有数。
然后,我们从 p1p_1pnp_n 不断地将 pip_iBB 中移除,加入到 AA 中。
i=1i=1 时,如果 p1>max{B}p_1>\max\{B\},那么 11 不可以和后面的任何数连边,否则可以连边。
i=1i=1 时可以连边: p1<max{B}p_1<\max\{B\} 的前提下,i=2i=2 时,如果 min{p1,p2}>max{B}\min\{p_1,p_2\}>\max\{B\},说明 p1<p2p_1<p_2p2p_22n2\sim npip_i 的最大值,那么 p2p_2 不可能和后面的点连边。
以此类推,我们只要不断比较 min{A}\min\{A\}max{B}\max\{B\} 即可。时间复杂度 O(nlogn)O(n\log n)
AC CodeCPP
#include <iostream>
#include <set>
using namespace std;
const int maxn = 2e5+5;
int t,n,a[maxn];
set<int>S1,S2;
int main(){
    cin >> t;
    while(t--){
        cin >> n;
        S1.clear();S2.clear();
        for(int i = 1;i<=n;i++){
            cin >> a[i]; S2.insert(a[i]);
        }
        bool flag=true;
        for(int i = 1;i<n;i++){
            S1.insert(a[i]); S2.erase(a[i]);
            if(*S1.begin() > *S2.rbegin()){
                flag = false;break;
            }
        }
        if(flag)cout<<"Yes\n"; else cout <<"No\n";
    }
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...