Codeforces Round 949 (Div. 2) A~D

2024-06-09 18:20
文章标签 codeforces round div 949

本文主要是介绍Codeforces Round 949 (Div. 2) A~D,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A. Turtle and Piggy Are Playing a Game (思维)

题意:

给出一个整数 x x x ,使得 l ≤ x ≤ r l \le x \le r lxr ,其中 l , r l, r l,r 为给定值。同时保证 2 l ≤ r 2l \le r 2lr
执行以下操作,直到 x x x 变为 1 1 1

  • 选择一个整数 p p p ,使得 p ≥ 2 p \ge 2 p2 p ∣ x p \mid x px (即 x x x p p p 的倍数)。
  • x x x 设置为 x p \frac{x}{p} px ,得分将增加 1 1 1

得分最初为 0 0 0 。询问得分最大为多少。

分析:

2 2 2的增长速度是最慢的,并且题目有 2 × l ≤ r 2 \times l \le r 2×lr,所以答案为 l o g 2 r log_2r log2r向下取整。

代码:

#include <bits/stdc++.h>using namespace std;int main() {int t;cin >> t;while (t--) {int l, r;cin >> l >> r;int ans = __lg(r);cout << ans << endl;}return 0;
}

B.Turtle and an Infinite Sequence (位运算)

题意:

给出一个无限长的序列 a 0 , a 1 , a 2 , … a_0, a_1, a_2, \ldots a0,a1,a2, 。对于每个非负整数 i i i ,初始值为 a i = i a_i = i ai=i
每一秒之后,序列中的每个元素都会同时发生变化。对于每个正整数 i i i a i a_i ai 将变为 a i − 1 ∣ a i ∣ a i + 1 a_{i - 1} \mid a_i \mid a_{i + 1} ai1aiai+1 a 0 a_0 a0 将变为 a 0 ∣ a 1 a_0 \mid a_1 a0a1
给出 m m m,询问 m m m秒之后, a n a_n an的值。

分析:

发现 a n a_n an m m m秒之后的答案为 [ n − m , n + m ] [n-m,n+m] [nm,n+m]这个区间里面所有数的异或和。我们直接枚举答案的二进制位 i i i,判断 i i i能否变成 1 1 1。只需找到第一个 x x x,满足 x ≥ l , x ≤ r , x > > i x \ge l, x \le r, x>>i xl,xr,x>>i & 1 1 1即可。

代码:

#include <bits/stdc++.h>using namespace std;
typedef long long LL;int main() {int t;cin >> t;while (t--) {LL n, m;cin >> n >> m;LL l = max(0LL, n - m);LL r = n + m;LL ans = 0;LL cnt = 0;while (l != r) {cnt++;l >>= 1;r >>= 1;}while (cnt--)r = (r << 1) ^ 1;cout << r << endl;}return 0;
}

C.Turtle and an Incomplete Sequence (位运算)

题意:

给出一个正整数组成的序列 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an但是现在序列不完整了。可能存在任意数量的索引 i i i ,使得 a i a_i ai 变成 − 1 -1 1 。让新序列为 a ′ a' a。保证对于原始序列 a a a ,要么 a i = ⌊ a i + 1 2 ⌋ a_i = \left\lfloor\frac{a_{i + 1}}{2}\right\rfloor ai=2ai+1 成立,要么 a i + 1 = ⌊ a i 2 ⌋ a_{i + 1} = \left\lfloor\frac{a_i}{2}\right\rfloor ai+1=2ai 成立。

换句话说,你需要找到另一个由正整数组成的序列 b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,,bn ,并且:

  • 对于从 1 1 1 n n n 的每个整数 i i i ,如果 a i ′ ≠ − 1 a'_i \ne -1 ai=1 ,则 b i = a i ′ b_i = a'_i bi=ai
  • 对于从 1 1 1 n − 1 n - 1 n1 的每个整数 i i i b i = ⌊ b i + 1 2 ⌋ b_i = \left\lfloor\frac{b_{i + 1}}{2}\right\rfloor bi=2bi+1 b i + 1 = ⌊ b i 2 ⌋ b_{i + 1} = \left\lfloor\frac{b_i}{2}\right\rfloor bi+1=2bi 成立。
  • 对于从 1 1 1 n n n 的每个整数 i i i 1 ≤ b i ≤ 1 0 9 1 \le b_i \le 10^9 1bi109

如果没有满足上述所有条件的序列 b 1 , b 2 , … , b n b_1, b_2, \ldots, b_n b1,b2,,bn ,则需要输出 − 1 -1 1

分析:

我们考虑将操作统一,即满足 b i = b i − 1 / 2 b_i=b_{i-1}/2 bi=bi1/2 或者满足 b i = b i − 1 × 2 b_i=b_{i-1} \times 2 bi=bi1×2 或者 b i = b i − 1 × 2 + 1 b_i=b_{i-1} \times 2+1 bi=bi1×2+1,并将操作转换成在二进制上考虑是将前一个数右移一位还是在末尾填上 0 0 0或者 1 1 1
我们接下来考虑从 x x x变成 y y y至少需要多少个操作,首先求出 x x x, y y y 的二进制最长公共前缀,然后将 x x x通过右移操作变成其最长公共前缀,然后再通过填 1 1 1或者填 0 0 0来变成 y y y。最后剩余的数通过反复乘 2 2 2或者除 2 2 2操作即可。

代码:

#include <bits/stdc++.h>using namespace std;
typedef long long LL;
const LL N = 5e5 + 10;
const LL mod = 1e9 + 7;LL gcd(LL a, LL b) {return b > 0 ? gcd(b, a % b) : a;
}int a[N];void solve() {int n;cin >> n;int bit[n + 5][32];for (int i = 1; i <= n; i++)cin >> a[i];vector<int> pos;int st = 0, en = 0;for (int i = 1; i <= n; i++) {if (a[i] != -1) {if (!st)st = i;pos.push_back(i);for (int j = 0; j < 32; j++) {bit[i][j] = ((a[i] >> j) & 1);}en = i;}}int f = 0;for (int i = st - 1; i >= 1; i--) {if (f == 0) {a[i] = a[i + 1] * 2;} else {a[i] = a[i + 1] / 2;}f ^= 1;}f = 0;for (int i = en + 1; i <= n; i++) {if (i == 1) {a[i] = 2;continue;}if (f == 0) {a[i] = a[i - 1] * 2;} else {a[i] = a[i - 1] / 2;}f ^= 1;}int len = pos.size();for (int i = 0; i < len - 1; i++) {int l = a[pos[i]], r = a[pos[i + 1]];int tmp = l;int len1 = 0, len2 = 0;while (tmp) {tmp /= 2;len1++;}tmp = r;while (tmp) {tmp /= 2;len2++;}int tot = 0;for (int j = 0; j < min(len1, len2); j++) {if (bit[pos[i]][len1 - j - 1] == bit[pos[i + 1]][len2 - j - 1])tot++;elsebreak;}int num = len1 + len2 - 2 * tot;if (pos[i + 1] - pos[i] < num || (pos[i + 1] - pos[i] - num) % 2 != 0) {cout << -1 << endl;return;}int num1 = len1 - tot;int num2 = len2 - tot;int po = pos[i] + 1;for (int j = 0; j < num1; j++) {a[po] = a[po - 1] / 2;po++;}for (int j = 0; j < num2; j++) {if (bit[pos[i + 1]][len2 - tot - j - 1] == 0) {a[po] = a[po - 1] * 2;} else {a[po] = a[po - 1] * 2 + 1;}po++;}int f = 1;for (po; po < pos[i + 1]; po++) {if (f == 1) {a[po] = a[po - 1] * 2;} else {a[po] = a[po - 1] / 2;}f ^= 1;}}for (int i = 1; i <= n; i++) {cout << a[i] << " ";}cout << endl;
}int main() {int t = 1;cin >> t;while (t--) {solve();}return 0;
}

D.Turtle and Multiplication (图论)

题意:

给一个整数 n n n ,并要求构造一个由满足以下条件的整数组成的序列 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an

  • 对于所有 1 ≤ i ≤ n 1 \le i \le n 1in 1 ≤ a i ≤ 3 ⋅ 1 0 5 1 \le a_i \le 3 \cdot 10^5 1ai3105
  • 对于所有 1 ≤ i ≤ j ≤ n − 1 1 \le i \le j \le n - 1 1ijn1 a i ⋅ a i + 1 ≠ a j ⋅ a j + 1 a_i \cdot a_{i + 1} \ne a_j \cdot a_{j + 1} aiai+1=ajaj+1

在所有这些序列中,找出具有最少个不同元素的序列。

分析:

如果我们都选质数,那么两对之间乘积不相同也就等价于两对质数不完全相同。那么将问题转化为在一个完全图上找欧拉路。如果我们只用奇数个质数,那么每个点度是偶数,有欧拉回路。如果用偶数个质数,就要删掉质数数量的一半减一条边,这样才会产生只有两个奇数度的点。

代码:

#include <bits/stdc++.h>using namespace std;
typedef long long LL;
const LL N = 3e5 + 10;
const LL mod = 1e9 + 7;
int n, m, st[N], g[1510][1510];
vector<int> pri;
stack<int> stk;void dfs(int u) {if (g[u][u])g[u][u] = 0, dfs(u);for (int i = 1; i <= m; i++)if (g[u][i])g[u][i] = g[i][u] = 0, dfs(i);stk.push(pri[u]);
}int main() {for (int i = 2; i <= 300000; i++) {if (!st[i])pri.push_back(i);for (int j = i * 2; j <= 300000; j += i)st[j] = 1;}int T;cin >> T;while (T--) {cin >> n;if (n == 1) {cout << 1 << endl;continue;}m = 1;while (m * (m + 1) / 2 - (m % 2 ? 0 : m / 2 - 1) < n - 1)m++;for (int i = 1; i <= m; i++)for (int j = 1; j <= m; j++)g[i][j] = 1;if (m % 2 == 0)for (int i = 3; i <= m; i += 2)g[i][i + 1] = g[i + 1][i] = 0;dfs(1);while (stk.size() && n) {cout << stk.top() << " ";stk.pop();n--;}while (stk.size())stk.pop();cout << endl;}return 0;
}

赛后交流

在比赛结束后,会在交流群中给出比赛题解,同学们可以在赛后查看题解进行补题。

群号: 704572101,赛后大家可以一起交流做题思路,分享做题技巧,欢迎大家的加入。

这篇关于Codeforces Round 949 (Div. 2) A~D的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045942

相关文章

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;

Codeforces Round 971 (Div. 4) (A~G1)

A、B题太简单,不做解释 C 对于 x y 两个方向,每一个方向至少需要 x / k 向上取整的步数,取最大值。 由于 x 方向先移动,假如 x 方向需要的步数多于 y 方向的步数,那么最后 y 方向的那一步就不需要了,答案减 1 代码 #include <iostream>#include <algorithm>#include <vector>#include <string>

CF#271 (Div. 2) D.(dp)

D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/474/problem/D We s

CF #278 (Div. 2) B.(暴力枚举+推导公式+数学构造)

B. Candy Boxes time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/488/problem/B There