Codeforces Round #641 (Div. 2)
A. Orac and Factors#
题目描述#
定义 为 的最小非 因数乘以
给定 ,求进行 次 后的 的值
思路#
模拟几个数字容易发现 进行过一次 之后, 一定是个偶数
偶数的最小非 因数一定是
点击查看代码
/********************
Author: Nanfeng1997
Contest: Codeforces Round #641 (Div. 2)
URL: https://codeforces.com/contest/{getProblemIndexes(problemCurrentPageList[i][0])[0]}/problem/A
When: 2022-03-17 22:38:20
Memory: 256MB
Time: 2000ms
********************/
#include <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
void solve() {
LL n, k; cin >> n >> k;
LL i = 0;
for(i = 2; i <= n / i; i ++ ) {
if(n % i == 0) {
break;
}
}
if(n % i) i = n;
if(k == 1) {
cout << n + i << "\n";
} else {
n += i;
k --;
cout << n + k * 2 << "\n";
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; cin >> T;
while(T --) solve();
return ~~(0 ^ _ ^ 0);
}
B. Orac and Models#
题目描述#
略...
思路#
进行 的 即可#
点击查看代码
/********************
Author: Nanfeng1997
Contest: Codeforces Round #641 (Div. 2)
URL: https://codeforces.com/contest/{getProblemIndexes(problemCurrentPageList[i][0])[0]}/problem/B
When: 2022-03-17 22:38:21
Memory: 256MB
Time: 3000ms
********************/
#include <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
const int N = 1e5 + 10;
struct node {
int val, id;
bool operator < (const node &T) const {
if(val != T.val)
return val < T.val;
return id < T.id;
}
}a[N]; //结构体没什么用,懒得删了~~~
int f[N];
void solve() {
int n; cin >> n;
for(int i = 1; i <= n; i ++ ) {
cin >> a[i].val;
a[i].id = i;
f[i] = 1;
}
int ans = 1;
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= i / j; j ++ ) {
if(i % j == 0) {
if(a[i].val > a[j].val)
f[i] = max(f[i], f[j] + 1);
if(j != 1 && a[i].val > a[i / j].val)
f[i] = max(f[i], f[i / j] + 1);
}
}
}
for(int i = 1; i <= n; i ++ ) {
ans = max(ans, f[i]);
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; cin >> T;
while(T --) solve();
return ~~(0 ^ _ ^ 0);
}
C. Orac and LCM#
题目描述#
- 给定长度为 的序列,
- 设可重集 。
- 设一个集合的最大公约数为最大正整数 ,满足集合内任意一个元素 均有 。
- 请你求出
- 。
思路#
首先:
所以原式可以化为
把 提出可得
可以线性求出,问题就转化成了如何快速求
设我们每次枚举到 第 个数字 为 ,那么可以将 中的 提出,就可以得到
可以预处理出后缀 ,枚举 即可计算答案
复杂度
源自
对于上述解法的证明:
如何证明这个等式?
对于每个质数 , 相当于求出了其指数的最小值和次小值之和, 则相当于求出了其指数的最小值,两者相减便是答案。
上述做法代码
点击查看代码
/********************
Author: Nanfeng1997
Contest: Codeforces Round #641 (Div. 2)
URL: https://codeforces.com/contest/{getProblemIndexes(problemCurrentPageList[i][0])[0]}/problem/C
When: 2022-03-17 22:38:22
Memory: 256MB
Time: 3000ms
********************/
#include <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
const int N = 1e5 + 10, M = 2e5 + 10;
int a[N], b[N];
/*
lcm是求两个数字的质因子的最大值
gcd是求两个数字的质因子的最小值
最大值的最小值 就是次小值.jpg
怎么快速的求呢?
我们可以先求一个 最小值和次小值 的和 就是 gcd(gcd(a_i * a_j))
然后求一个最小值 gcd(gcd(a_i, a_j))
*/
void solve() {
int n; cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
for(int i = n; i >= 1; i -- ) b[i] = __gcd(b[i + 1], a[i]);
LL ans = 0;
for(int i = 1; i <= n; i ++ ) {
ans = __gcd(ans, 1LL * a[i] * b[i + 1]);
}
printf("%lld", ans / b[1]);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; // cin >> T;
while(T --) solve();
return ~~(0 ^ _ ^ 0);
}
另一种做法
点击查看代码
/********************
Author: Nanfeng1997
Contest: Codeforces Round #641 (Div. 2)
URL: https://codeforces.com/contest/{getProblemIndexes(problemCurrentPageList[i][0])[0]}/problem/C
When: 2022-03-17 22:38:22
Memory: 256MB
Time: 3000ms
********************/
#include <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
const int N = 1e5 + 10, M = 2e5 + 10;
int a[N], f[N];
int pre[N], suf[N];
void solve() {
/*
如果p^k | ans, 那么必定有多于 n-1 个数字可以满足 p^k | a_i
如果是 少于 n - 1 个,那么必定有两个数字 a_i, a_j,满足 p^k not| lcm(a_i, a_j)
因此不成立
因此维护前缀gcd和后缀gcd即可
*/
int n; cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
for(int i = 1; i <= n; i ++ ) pre[i] = __gcd(pre[i - 1], a[i]);
for(int i = n; i >= 1; i -- ) suf[i] = __gcd(suf[i + 1], a[i]);
int g = 0;
for(int i = 1; i <= n; i ++ ) {
f[i] = __gcd(pre[i - 1], suf[i + 1]);
g = __gcd(g, f[i]);
}
LL ret = 1;
for(int i = 1; i <= n; i ++ ) {
ret = ret * f[i] / g;
}
cout << ret * g;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; // cin >> T;
while(T --) solve();
return ~~(0 ^ _ ^ 0);
}
D. Orac and Medians#
询问数组中的数字能否通过若干次将任意区间内的数字都赋值为其中位数这个操作,使得整个序列的数字都变成
思路#
如果数组中不存在 , 那么一定是不可能的,下面我们考虑数组中存在 的情况
如果数组的长度为 ,那么一定可以,面我们考虑数组中存在 且长度不为 的情况
假如存在 并且 那么一定可以从这两个位置往外扩散使得最终的结果均为
假如存在 并且 那么一定可以从这两个数字往外扩散将其都变为 大于等于 的数字,直到遇到一个 ,使得所有的数字都变为
点击查看代码
/********************
Author: Nanfeng1997
Contest: Codeforces Round #641 (Div. 2)
URL: https://codeforces.com/contest/{getProblemIndexes(problemCurrentPageList[i][0])[0]}/problem/D
When: 2022-03-17 22:38:23
Memory: 256MB
Time: 2000ms
********************/
#include <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
bool solve() {
int n, k; cin >> n >> k;
vector<int> a(n); int cnt = 0;
for(int i = 0; i < n; i ++ ) {
cin >> a[i];
if(a[i] == k) cnt ++;
}
if(!cnt) return false;
if(n == 1) return true;
for(int i = 0; i + 1 < n; i ++ ) if(a[i] >= k && a[i + 1] >= k) {
return true;
}
for(int i = 0; i + 2 < n; i ++ ) if(a[i] >= k && a[i + 2] >= k) {
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; cin >> T;
while(T --) cout << (solve() ? "yes" : "no") << "\n";
return ~~(0 ^ _ ^ 0);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!