牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)

news/2025/2/25 5:53:47

文章目录

  • 牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)
    • A. 夹心饼干
    • B. C. 食堂大作战(思维)
    • D. 小苯的排列计数(差分、树状数组)
    • E. 和+和(大根堆,前缀和)
    • F. 怎么写线性SPJ (思维、递归)

牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)

A. 夹心饼干

语法基础题

#include<bits/stdc++.h>
using namespace std;

int main(){
		
	string s;
	cin >> s;
	cout << (s[0] == s[2] ? "YES" : "NO") << endl;

	return 0;
}

B. C. 食堂大作战(思维)

显然,只要没有两个窗口同时关门,即合法方案。

对于方案,按照关门时间排序,依次输出即可。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 5;

pair<int, int> a[maxn];

int main(){
		
	int n;
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i].first;
        a[i].second = i;
    } 
    
    sort(a+1, a+1+n);
    
    int flag = 1;
    for(int i = 1; i <= n; i++){
        if(a[i].first == a[i-1].first){
            flag = 0;
            break;
        }
    }
    if(flag){
        cout << "YES" << endl;
    }
    else cout << "NO" << endl;
    
	return 0;
}

D. 小苯的排列计数(差分、树状数组)

对于样例:

10

7 7 7 5 5 1 1 1 1 1 1

首先,标黄色的元素的值是确定的。

其次,我们依次来看:

  1. 72,在此处,可以选择 8,9,10。即,有三种选择。(这里表示第二个 7,其他相同形式同理)
  2. 73,在此处,可以选择 8,9,10。但是,这时已经在 72处使用过一个元素,还有两种选择可用。
  3. 52,在此处,可以选择 6,8,9,10。但是,这时已经在 72 和 73 处使用过两个元素,还有两种选择可用。
  4. 依次类推…

对于一个方案,在某元素 x:

  1. 如果第一次出现时,该元素在只能在此处,在此处贡献一种组合的可能。
  2. 如果元素 x 不是第一次出现时:
    • 如有大于该元素的选择,可选择元素的个数等于此处贡献的组合。
    • 如没有大于该元素的选择,则方案不合法。

使用差分和树状数组配合,即可实现,求[x, n] 中的可用元素个数。


#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 1e6 + 5;
const ll mod = 998244353;

ll a[maxn], tree[maxn];

int lowbit(int x){
    return x & (-x);
}

void add(int i, int value){
    while(i < maxn){
        tree[i] += value;
        i += lowbit(i);
    }
}

int sum(int i){
    int res = 0;
    while(i > 0){
        res += tree[i];
        i -= lowbit(i);
    }
    return res;
}

int main(){
    
    int ncase;
    cin >> ncase;
    
    while(ncase--){
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        
        for(int i = 1; i <= n; i++) tree[i] = 0;
        for(int i = 1; i <= n; i++) add(i, 1);
        
        ll res = 1;
        for(int i = 1; i <= n; i++){
            if(a[i] != a[i-1]){
                if(a[i] > a[i-1]  && i != 1){
                    res = 0;
                    break;
                }
                add(a[i], -1);
            }
            else{
                int cnt = sum(n) - sum(a[i]);	// 差分
                if(cnt == 0){
                    res = 0;
                    break;
                }
                else{
                    res = res * cnt % mod;
                    add(a[i]+1, -1);
                }
            }
        }
        cout << res << endl;
    }

    
	return 0;
}

E. 和+和(大根堆,前缀和)

题意等价于:选一个 x,在 a[1,x] 中选 m 个最小的数,在 b[x+1, n] 中选 m 个最小的数,使得选出的数sum最小。

枚举所有可能的 x,只要能 O(1) 或者 O(log(n)) 求出 a[1,x] 中 m 个最小的数的和,即可。


对于a数组,维护一个大小为 m 的大根堆,即前 i 个元素中最小的 m 个元素。

依次遍历a数组,插入新值a[i],删除最大的元素,维护sum,维护前缀min即可。


对于 b 数组,逆序遍历,操作同上。


#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 2e5 + 5;

ll a[maxn], b[maxn];
ll pre[maxn], suf[maxn];

priority_queue<int> qu;

int main(){
    
    int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++) cin >> a[i];
	for(int i = 1; i <= n; i++) cin >> b[i];
	
	ll sum = 0;
	for(int i = 1; i <= n; i++){
		sum += a[i];
		qu.push(a[i]);
		if(i > m){
			sum -= qu.top();
			qu.pop();			
		}
		pre[i] = sum;
	} 
	
	sum = 0;
	while(!qu.empty()) qu.pop();
	
	for(int i = 1; i <= n; i++){
		sum += b[n-i+1];
		qu.push(b[n-i+1]);
		if(i > m){
			sum -= qu.top();
			qu.pop();			
		}
		suf[n-i+1] = sum;
	}
	
	ll res = 2e9;
	for(int i = m; i+m-1 < n; i++){
		res = min(res, pre[i] + suf[i+1]);
	}
	cout << res << endl;
    
	return 0;
}

F. 怎么写线性SPJ (思维、递归)

手搓几个样例后,容易想到一个事实:

令 mid = ( l + r ) / 2,如果 a[mid] 是一个 “唯一元素”,接下来,只需要考虑 (l, mid-1) 和 (mid+1, r) 即可。

用相同的思路处理(l, mid-1) 和 (mid+1, r),直到区间大小为 1。(递归)

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 2e5 + 5;

int a[maxn];

void dfs(int l, int r, int num){
	if(l > r) return; 
	int mid = l + r >> 1;
	a[mid] = num;
	dfs(l, mid-1, num+1);
	dfs(mid+1, r, num+1);
}

int main(){
    
    int n;
	cin >> n;
	
	dfs(1, n, 1); 
	
	set<int> s;
	for(int i = 1; i <= n; i++) s.insert(a[i]);
	cout << s.size() << endl;
	for(int i = 1; i <= n; i++) cout << a[i] << " ";
    
	return 0;
}

http://www.niftyadmin.cn/n/5865058.html

相关文章

小程序高度问题背景scss

不同的机型&#xff0c;他的比例啥的都会不一样&#xff0c;同样的rpx也会有不同的效果。所以这里选择了取消高度。 <view class"box-border" :style"{padding-top: ${navHeight}px,}"><!-- 已登录 --><view v-if"userStore.userInfo&…

Image Collections操作

在Google Earth Engine&#xff08;GEE&#xff09;中处理影像集合&#xff08;Image Collections&#xff09;是遥感数据分析的核心操作。以下是详细的步骤和示例代码&#xff0c;涵盖影像集合的常见操作&#xff1a; 1. 影像集合基础 影像集合是GEE中存储多幅影像的数据结构…

文件上传-Windows点空格点绕过

[题目信息]&#xff1a; 题目名称题目难度文件上传-Windows点空格点绕过1 [题目考点]&#xff1a; Windowsw文件特性考察[Flag格式]: SangFor{UDOaJfziTs4c-dceIyGxa53-Ybrg9dtF}[环境部署]&#xff1a; docker-compose.yml文件或者docker tar原始文件。 docker-compose u…

数据同步的中间件

以下是10个支持MySQL、HBase、ClickHouse、HDFS等不同数据库之间数据同步的GitHub项目推荐&#xff1a; 项目名称语言主要特点支持的数据库GitHub链接DataXPython阿里巴巴开源的数据同步工具&#xff0c;支持多种数据库和文件系统。MySQL、ClickHouse、HDFS等GitHub链接Apache…

STM32-智能小车项目

项目框图 ST-link接线 实物图&#xff1a; 正面&#xff1a; 反面&#xff1a; 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…

Spring Cloud Gateway 网关的使用

在之前的学习中&#xff0c;所有的微服务接口都是对外开放的&#xff0c;这就意味着用户可以直接访问&#xff0c;为了保证对外服务的安全性&#xff0c;服务端实现的微服务接口都带有一定的权限校验机制&#xff0c;但是由于使用了微服务&#xff0c;就需要每一个服务都进行一…

云电脑接入DeepSeek?探讨ToDesk云电脑、海马云、顺网云的AI潜能

目录 前言一、云电脑相比实体电脑部署DeepSeek的优势二、DeepSeek云电脑实操1、ToDesk云电脑2、海马云3、顺网云 三、DeepSeek R1模型与云电脑适配性分析1、基本配置分析2、文本推理测试 四、云电脑选型看点1、跨平台兼容性2、文件存储3、关键技术4、安全与隐私5、用户体验 五、…

put data item into sotfhsm as data objects in different block size

#!/bin/bash # 该脚本用于向智能卡写入4096个数据对象&#xff0c;每个token最多容纳256个数据对象 # 当前token满载时&#xff0c;自动初始化新tokenSTART_TIME$(date %s%3N) # 模块路径&#xff0c;根据实际情况调整 MODULE_PATH"/home/ubuntu/Documents/HSM/20250106/S…