Round 1019(div2) CD

Round 1019(div2)

C - Median Splits(中位数)

题意:把数组分成三段,使得三段的中位数组成的数组的中位数小于等于kkk。

记录sumisum_isumi为前iii个小于等于kkk的个数。然后把满足中位数小于等于kkk的前缀和后缀存下来。

如果最前的前缀和最后的后缀中间至少有一个数,就满足条件了。

否则如果前缀个数或后缀个数大于2也满足条件。再否则讨论两个前缀和两个后缀的情况,如果两个前缀之间中位数小于等于k也满足,后缀同理讨论。

为什么前缀个数大于2就满足条件?

以前缀为例,取最前面的两个合法前缀,如果第一个前缀长度是偶数,那么它到后一个前缀之间的区间也满足,因为它的小于等于k的数正好有一半,所以后一个前缀能满足条件一定是后面出现的小于等于k的数更多。如果第一个前缀长度是奇数,那么下一个满足条件的前缀一定挨着它且这个前缀长度是偶数(因为第一个前缀是最前的,它是奇数那么肯定是单独一个小于等于k的数,那么前两个数就至少有一个数小于等于k了),如果后面还有满足条件的前缀就和上面讨论的一样。所以只要有三个前缀就一定满足。

cpp 复制代码
void solve(){
    int n,k;
    cin>>n>>k;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    vector<int> pre(n+1),suf(n+10);
    for(int i=1;i<=n;i++){
        pre[i]=pre[i-1]+(a[i]<=k);
    }
    for(int i=n;i>=1;i--){
        suf[i]=suf[i+1]+(a[i]<=k);
    }
    vector<int> l,r;
    for(int i=1;i<=n;i++){
        if(2*pre[i]>=i)l.push_back(i);
    }
    for(int i=n;i>=1;i--){
        if(2*suf[i]>=(n-i+1))r.push_back(i);
    }
    bool flag =false;
    if((l.size()>2)||(r.size()>2)){
        flag =true;
    }
    if(l.size()==2){
        if(2*(pre[l[1]]-pre[l[0]])>=(l[1]-l[0])){
            flag =true;
        }
    }
    if(r.size()==2){
        if(2*(suf[r[1]]-suf[r[0]]) >=(r[0]-r[1])){
            flag =true;
        }
    }
    if((!l.empty())&&(!r.empty())){
       if(l[0]+1<r[0]){
            flag =true;
        }
    }
    if(flag)cout<<"YES\n";
    else cout<<"NO\n";
}

D Local Construction(思维+构造)

题意:一开始有一个排列,第奇数时刻把所有 pi<=pi−1且pi<=pi+1p_i<=p_{i-1} 且p_i<=p_{i+1}pi<=pi−1且pi<=pi+1的位置保留,其它删去,偶数时刻则是保留pi>=pi−1与pi>=pi+1p_i>=p_{i-1} 与 p_i>=p_{i+1}pi>=pi−1与pi>=pi+1的位置。现在给出每个位置被删掉的时刻,求一个合法的排列。

模拟,按时刻从小到大枚举,把所有这一时刻的数都取出来,分为−1-1−1的左边和右边的两部分。然后如果是奇数时刻左边从大到小给数,右边从小到大给数(类似于-1是二次函数的那个极值点)。偶数时刻左边从小到大,右边从大到小。这样可以保证这些数一定在这一时刻被删掉。

然后最后剩下的一个数给没被删的那个位置。

cpp 复制代码
void solve() {
    int n;
    std::cin >> n;
    std::vector<int> a(n + 1);
    for (int i = 1; i <= n; ++ i) {
    	std::cin >> a[i];
    }

    std::vector<int> ans(n + 1);

    int m = *std::max_element(a.begin(), a.end());
    int l = 1, r = n;
    for (int i = 1; i <= m; ++ i) {
    	std::vector<int> b[2];
    	int x = 0;
    	for (int j = 1; j <= n; ++ j) {
    		x |= a[j] == -1;
    		if (a[j] == i) {
    			b[x].push_back(j);
    		}
    	}

    	reverse(b[1].begin(),b[1].end());
    	for (auto & j : b[0]) {
    		if (i & 1) {
    			ans[j] = r -- ;
    		} else {
    			ans[j] = l ++ ;
    		}
    	}
    	for (auto & j : b[1]) {
    		if (i & 1) {
    			ans[j] = r -- ;
    		} else {
    			ans[j] = l ++ ;
    		}
    	}
    }
    for (int i = 1; i <= n; ++ i) {
    	if (ans[i] == 0) {
    		ans[i] = l;
    		break;
    	}
    }
    for (int i = 1; i <= n; ++ i) {
    	std::cout << ans[i] << " \n"[i == n];
    }
}
相关推荐
DFT计算杂谈几秒前
Janus单层Cr2SSe中的应变可调多压电效应与谷电子学
人工智能·算法·机器学习
今天AI了吗1 分钟前
从 LLM 到 Agent Skill:把 AI 底层概念串起来
数据库·人工智能·sql·深度学习·神经网络·算法·机器学习
hanlin0325 分钟前
动态规划专练:力扣第1035、392题
算法·leetcode·动态规划
淡海水26 分钟前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
不正经学生1 小时前
C语言大小端字节序:内存里字节的排列顺序
c语言·开发语言·arm开发·c++·算法·c#
大模型探索者1 小时前
2026金融大模型训推平台选型指南:主流厂商横向对比与私有化落地
人工智能·算法·金融
小则又沐风a2 小时前
负载均衡式在线OJ---------第二幕
linux·c++·后端
a3535413822 小时前
C++项目如何架构优化
java·c++·架构
键盘会跳舞2 小时前
C++:智能指针源码级深度拆解——从 RAII 思想到引用计数的内存安全体系
c++·智能指针·unique_ptr·shared_ptr·weak_ptr
依然鸣2 小时前
PTA团体程序设计天梯赛L2真题讲解L2-001-004
经验分享·学习·算法·深度优先·pat考试