比赛链接

A

题意

给 \(n\) 个正整数,找到三个数,使得他们的和为奇数,输出他们的下标。

题解

知识点:贪心。

找到三个奇数或者一个奇数两个偶数即可,其他情况无解。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
int n;
cin >> n;
vector<int> v1, v2;
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
if (x & 1) v1.push_back(i);
else v2.push_back(i);
}
if (v1.size() >= 3) {
cout << "YES" << '\n';
cout << v1[0] << ' ' << v1[1] << ' ' << v1[2] << '\n';
}
else if (v1.size() >= 1 && v2.size() >= 2) {
cout << "YES" << '\n';
cout << v1[0] << ' ' << v2[0] << ' ' << v2[1] << '\n';
}
else return false;
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << "NO" << '\n';
}
return 0;
}

B

题意

给 \(n\) 个正整数 \(a_i\) 。选择一个 \(k>1\) ,随后将 \(a_i\) 分成 \(k\) 个连续非空段,使得每段的和 \(b_i\) 的最大公约数 \(\gcd(b_1,\cdots,b_k)\) 最大。

题解

知识点:数论,贪心。

对于任意 \(k\) 的任意划分有答案 \(\gcd(b_1,\cdots,b_k)\) ,根据 \(\gcd(a,b) = \gcd(a+b,b)\) ,即 \(a\) 和 \(b\) 的最大公因数一定也是 \(a+b\) 的因子,那么 \(\gcd(b_1+b_2,b_3,\cdots,b_k) \geq \gcd(b_1,\cdots,b_k)\) ,所以任意两段合并代替合并前的两段不会让答案变差,因此最好的情况一定出现在只分为两段的情况。

因此,我们只要求出 \(\max_\limits{1\leq i \leq n-1}\gcd(a[1,i],a[i+1,n])\) 即可。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; ll a[200007];
bool solve() {
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i], a[i] += a[i - 1];
ll ans = 1;
for (int i = 1;i <= n - 1;i++) {
ans = max(ans, gcd(a[i], a[n] - a[i]));
}
cout << ans << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

C

题有问题。

D

题意

有一个数字 \(n \in[1,10^9]\) ,告诉你 \(n\) 的二进制位 \(1\) 的个数 \(cnt\)。

随后可以执行不超过 \(30\) 次操作:选择一个 \(x\) ,使得 \(n\) 减去 \(x\) ,得到新的 \(n\) 的二进制位 \(1\) 的个数 \(cnt\) 。

最后,你需要猜出 \(n\) 是多少。

题解

知识点:位运算,枚举。

由于 \(n\) 最多会有 \(30\) 个 \(1\) ,我们可以探测每一位是否为 \(1\) 。

具体的说,我们探测第 \(i\) 位是否为 \(1\) ,可以减去 \(2^{i-1}\) 。如果这位是 \(1\) ,那么新的个数 \(cnt' = cnt-1<cnt\) ,否则一定有 \(cnt'\geq cnt\) 。但是,这个结论的前提是,我们是对原本的 \(n\) 做减法。考虑到操作会改变 \(n\) ,因此我们第 \(i-1\) 位探测完后,第 \(i\) 位的探测减去的应该是 \(2^{i-1} - 2^{i-2}\) ,这样可以抵消上一次操作,等效于对原来的 \(n\) 减去 \(2^{i-1}\) 。

要注意的是,如果减的数超过 \(n\) 那么也会错,即我们不能探测超过 \(n\) 最高位二进制的数。为了防止超出,我们可以记录探测为 \(1\) 的位数 \(tot\) ,如果 \(tot = cnt\) 那么可以立刻停止,因为此时答案已经满足要求了。

时间复杂度 \(O(1)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; int query(int x) {
int cnt;
cout << "- " << x << endl;
cin >> cnt;
return cnt;
} void answer(int n) {
cout << "! " << n << endl;
} bool solve() {
int cnt;
cin >> cnt;
int ans = 0, tot = 0;
if (query(1) < cnt) ans += 1, tot++;
for (int i = 1;i < 30 && tot < cnt;i++) {
if (query((1 << i) - (1 << (i - 1))) < cnt) ans += 1 << i, tot++;
}
answer(ans);
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

E

题意

给定一个区间 \([L,R]\) ,求 \(\gcd(i,j)\) 的种类,其中 \(i,j\in[L,R]\) 。

题解

知识点:整除分块。

设 \(\gcd(i,j) = d\) 我们考虑讨论 \(d\) 的大小:

  1. 当 \(\left\lfloor \dfrac{R}{2} \right\rfloor + 1 \leq d\) ,那么对于最小的倍数 \(2d\) ,也一定有 \(2d > R\) , 所以不存在 \([L,R]\) 的数满足这个范围的 \(d\) 。
  2. 当 \(L \leq d \leq \left\lfloor \dfrac{R}{2} \right\rfloor\) ,我们一定可以构造 \(\gcd(d,2d) = d\) ,其中 \(L \leq d < 2d \leq R\) 。
  3. 当 \(d \leq L - 1\) ,我们尝试构造大于等于 \(L\) 的最小的一组数 \(L \leq d \cdot \left\lceil \dfrac{L}{d} \right\rceil < d \cdot \left( \left\lceil \dfrac{L}{d} \right\rceil +1\right)\) ,这两个数满足 \(d \cdot \left\lceil \dfrac{L}{d} \right\rceil < d \cdot \left( \left\lceil \dfrac{L}{d} \right\rceil +1\right) \leq R\) ,则 \(d\) 是合法的,否则一定不合法。

对于前两类我们可以轻易求出个数,但第三类,显然我们不可能一个一个枚举 \(d\in[1,L-1]\) 。

实际上,我们发现会存在许多连续区间的 \(d\) ,其 \(\left\lceil \dfrac{L}{d} \right\rceil\) 的值是一样的,大约有 \(\sqrt L\) 个。假设 \([l,r]\) 区间的 \(d\) 满足 \(\left\lceil \dfrac{L}{d} \right\rceil = \left\lceil \dfrac{L}{l} \right\rceil\) ,那么若 \(d\) 满足 \(l \leq d \leq \min \left(r,\left\lfloor \dfrac{R}{\left\lceil \dfrac{L}{d} \right\rceil + 1} \right\rfloor \right)\) 则构造的数不会超 \(R\) ,是合法的。

那么这个问题现在就变成一个整除分块问题,为了方便,我们把取上整都转化为取下整,即 \(\left\lceil \dfrac{L}{d} \right\rceil = \left\lfloor \dfrac{L-1}{d} \right\rfloor + 1\) 。已知左端点 \(l\) 和 \(\left\lfloor \dfrac{L-1}{l} \right\rceil = k\) ,求最大的右端点 \(r\) 满足 \(\left\lfloor \dfrac{L-1}{i} \right\rfloor = k,i \in [l,r]\) 。为了在 \(l\) 的基础上将 \(i\) 向上逼近,我们将整除等式转化一个不等式 \(i \cdot k \leq L-1\) , \(r\) 即为 \(i\) 的最大值 \(\left\lfloor \dfrac{L-1}{k} \right\rfloor\) 。

现在我们就可以从 \(d = 1\) 开始枚举,每次可以枚举一个区间。

时间复杂度 \(O(\sqrt{L})\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
ll L, R;
cin >> L >> R;
ll ans = max(0LL, R / 2 - L + 1);
for (int l = 1, r;l < L;l = r + 1) {
int k = (L - 1) / l;
r = (L - 1) / k;
ans += max(0LL, min((ll)r, R / (k + 2)) - l + 1);
}
cout << ans << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

Codeforces Round #846 (Div. 2) A-E的更多相关文章

  1. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  2. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  3. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  4. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  5. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  6. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  7. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  8. Codeforces Round #371 (Div. 1)

    A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...

  9. Codeforces Round #268 (Div. 2) ABCD

    CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...

  10. 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts

    题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...

随机推荐

  1. 记一次 .NET 某娱乐聊天流平台 CPU 爆高分析

    一:背景 1.讲故事 前段时间有位朋友加微信,说他的程序直接 CPU=100%,每次只能手工介入重启,让我帮忙看下到底怎么回事,哈哈,这种CPU打满的事故,程序员压力会非常大, 我让朋友在 CPU 高 ...

  2. iptables介绍和基本使用

    iptables 防火墙是什么 防火墙好比一堵真的墙,能够隔绝些什么,保护些什么. 防火墙的本义是指古代构筑和使用木制结构房屋的时候,为防止火灾的发生和蔓延,人们将坚固的石块堆砌在房屋周围作为屏障,这 ...

  3. ES6 学习笔记(十)Map的基本用法

    1 基本用法 Map类型是键值对的有序列表,而键和值都可以是任意类型.可以看做Python中的字典(Dictionary)类型. 1.1 创建方法 Map本身是一个构造函数,用来生成Map实例,如: ...

  4. or、and表达式

    or 逻辑表达式 result = a or b 如果a为空则执行or后面的b,如果a不为空,则执行or前面的a 即:赋值运算中,如果or前面为真,就不会去执行or后面的,如果or前面为假才会执行or ...

  5. 再来一次,新技术搞定老业务「GitHub 热点速览 v.22.44」

    上上周 Next.js 新版本火了一把,这不本周热点趋势就有了一个 Next.js 13 新特性构建的网站,虽然它只是个实验性项目.同样可以搞定一些业务的还有 lama-cleaner,不过它并不是个 ...

  6. 23、有一个字符串,包含n个字符,编写一函数,将此字符串中从第m个字符开始的全部字符串复制成另一个字符串

    /* 有一个字符串,包含n个字符,编写一函数,将此字符串中从第m个字符开始的全部字符串复制成另一个字符串 */ #include <stdio.h> #include <stdlib ...

  7. Redis系列11:内存淘汰策略

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  8. 关于linux上实现arp攻击截取密码

    前言 这几天简单的研究了一下arp攻击,有一些进展,记录一下 环境准备 这里我是利用arpspoof 这个软件简单实现arp攻击,这个命令是属于dsniff 软件包中的 所以首先安装软件 sudo a ...

  9. day13 I/O流——字节输入输出流、字符输入输出流 & File常用类 & (字节)复制大文件

    day13 I/O流 定义:数据在两设备传输称为流,流是一组有顺序的,有起点和终点的字节集合 I 是input的缩写,表示输入流 O是output缩写,表示输出流 字节流(视频等) 输入InputSt ...

  10. 推荐一款采用 .NET 编写的 反编译到源码工具 Reko

    今天给大家介绍的是一款名叫Reko的开源反编译工具,该工具采用C#开发,广大研究人员可利用Reko来对机器码进行反编译处理.我们知道.NET 7 有了NativeAOT 的支持,采用NativeAOT ...