当前位置: 首页 > article >正文

牛客周赛 Round 60(思维、逆元、组合数、概率DP)

文章目录

  • 牛客周赛 Round 60(思维、逆元、组合数、概率DP)
    • A. 困难数学题
    • B. 构造序列
    • C. 连点成线
    • D. 我们N个真是太厉害了(思维)
    • E. 折返跑(小费马定理求逆元、组合数)
    • F. 口吃(概率DP)

牛客周赛 Round 60(思维、逆元、组合数、概率DP)


F题,概率DP不会,学了再补


A. 困难数学题

  • x ^ x = 0
  • 0 ^ x = x
  • ^ 表示二进制异或
#include<bits/stdc++.h>

using namespace std;

int main(){
	
	cout << 0 << endl;
	
	return 0;
}

B. 构造序列

注意是ABAB,还是ABABA

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

int main(){
	
    ll a, b;
    cin >> a >> b;
    
    cout << min(a, b) * 2 + (a != b) << endl;
    
	return 0;
}

C. 连点成线

统计每行每列出现的最大值和最小值,做差取max即可,

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

vector<int> row[maxn], column[maxn];

int main(){
	
	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		int x, y;
		cin >> x >> y;
		row[x].push_back(y);
		column[y].push_back(x);
	}
	
	int res = 0;
	for(int i = 1; i <= n; i++){
		if(row[i].size() > 1){
			sort(row[i].begin(), row[i].end());
			res = max(res, *(row[i].end() - 1) - row[i][0]);	// row[i].end() 是指针,表示row[i]最后一个元素的后一位的地址
		}
		if(column[i].size() > 1){
			sort(column[i].begin(), column[i].end());
			res = max(res, *(column[i].end() - 1) - column[i][0]);
		}
	}
	cout << res << endl;
	
	return 0;
}

D. 我们N个真是太厉害了(思维)

如果当前序列 A,任选元素加和,可以构成出排列 1、2、3、…、mx。

向序列A中加入元素 x 后,如果 x <= mx +1,这时可以构成的排列变为 1、2、3、…、mx、mx+1、…、mx + x。

根据题意,对a排序,依次遍历,不断维护mx,并判断 a[i] 是否小于等于 mx+1。如出现 a[i] > mx+1,则 mx+1 为第一个不能被加和得到的数。

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

int a[maxn];

int main(){
	
	int ncase;
    cin >> ncase;
    
    while(ncase--){
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        
        sort(a+1, a+1+n);
        
        int res = -1;
        if(a[1] != 1) res = 1;
        else{
            int mx = 1;
            for(int i = 2; i <= n; i++){
                if(a[i] <= mx + 1) mx += a[i];
                else{
                    res = mx + 1;
                    break;
                }
                if(mx >= n) break; // 一点点优化
            }
        }
        if(res == -1) cout << "Cool!" << endl;
        else cout << res << endl;
    }
	
	return 0;
}

E. 折返跑(小费马定理求逆元、组合数)

对于一次查询 n 和 m,可以理解为在 n-2 个点中选 m - 1 个点出来,选择的方案数即为结果。(n-2:去除掉开始和结尾)

综上: r e s = C n − 2 m − 1 res = C_{n-2}^{m-1} res=Cn2m1

用小费马定理求逆元计算组合数即可。
PS:第一眼以为是DP,稍微写一下状态转移方程,就可以发现是组合数。

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

const ll mod = 1e9 + 7;
const int maxn = 1e6 + 5;

ll qpow(ll a, ll b){
    ll res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a *= a;
        a %= mod;
        b >>= 1;
    }
    return res;
}

ll f[maxn], p[maxn];
ll C(ll a, ll b){
    return f[a] * p[b] % mod * p[a-b] % mod;
}

int main(){
	
    f[0] = 1;
    for(int i = 1; i < maxn; i++) f[i] = f[i-1] * i % mod;
    for(int i = 0; i < maxn; i++) p[i] = qpow(f[i], mod-2); // 费马小定理求逆元
    
	int ncase;
	cin >> ncase;
	while(ncase--){
		ll n, m;
        cin >> n >> m;
		n -= 2; m -= 1;
        if(n <= 0 || m <= 0) cout << 1 << endl;
        else cout << C(n, m) << endl;
	}
	
	return 0;
}

F. 口吃(概率DP)

先挖坑。

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

const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;
ll a[maxn], b[maxn];

ll qpow(ll a, ll b){
	ll res = 1;
	while(b){
		if(b & 1) res *= a;
		res %= mod;
		a *= a;
		a %= mod;
		b >>= 1;
	}
	return res;
}

int main(){
	
	int n;
	cin >> n;
	for(int i = 1; i < n; i++) cin >> a[i];
	for(int i = 1; i < n; i++) cin >> b[i];
	
	ll num = 1 + b[1] * qpow(a[1], mod-2) % mod;
	ll res = num;
	for(int i = 2; i < n; i++){
		num = (a[i] + b[i]) * (a[i] + b[i]) % mod + num * b[i] % mod * b[i] % mod;
		num = num * qpow(a[i], mod-2) % mod * qpow(a[i], mod-2) % mod;
		res = (res + num) % mod;
	}
	
	cout << (res + 1) % mod << endl;
	
	return 0;
}

http://www.kler.cn/news/316683.html

相关文章:

  • 箭头与数字识别系统源码分享
  • STM32F407单片机编程入门(十六) DMA详解及ADC-DMA方式采集含源码
  • 『功能项目』主角属性值显示【75】
  • html+css+js网页设计 旅游 穷游10个页面
  • 【Qt笔记】QTabWidget控件详解
  • 828华为云征文 | 云服务器Flexus X实例,搭建MC我的世界服务器
  • 力扣773:滑动谜题
  • K8s Calico替换为Cilium,以及安装Cilium过程
  • 进阶SpringBoot之集合 Redis
  • html/css怎么禁用浏览器自动填写
  • 使用 Nginx 搭建 Webdav 服务
  • 安全通信网络等保
  • Android OpenGLES2.0开发(二):环境搭建
  • 付费电表系统的通用功能和应用过程参考模型(中)
  • GPT1-GPT3论文理解
  • 关于wordPress中的用户登录注册等问题
  • MySQL函数介绍--日期与时间函数(二)
  • react hooks--useMemo
  • linux文件IO 缓存,行缓存,三类读写函数,fprint,sprintf等
  • 计算机网络-小型综合网络的搭建涉及到无线路由交换安全
  • Qt C++,QByteArray读取一个超过2GB的文件,写一类封装一下
  • Windows 配置docker和ubuntu系统
  • css如何设置间距
  • 防火墙详解(一) 网络防火墙简介
  • 网络爬虫到底难在哪里?
  • 数据结构(十二)——栈(下)(面试题)
  • Informer模型复现项目实战
  • 数据库性能优化之分表
  • ollama 部署教程(window、linux)
  • 自定义类型