Codeforces Global Round 1

A. Parity

签.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 100010
 5 int b, k, a[N];
 6
 7 int main()
 8 {
 9     while (scanf("%d%d", &b, &k) != EOF)
10     {
11         int res = 0;
12         for (int i = 1; i <= k; ++i) scanf("%d", a + i);
13         int base = 1;
14         for (int i = k; i >= 1; --i)
15         {
16             res = (res + a[i] * base % 2) % 2;
17             base = base * b % 2;
18         }
19         puts(res % 2 ? "odd" : "even");
20     }
21     return 0;
22 }

做的时候卡了一会儿

因为想用费马小定理

认为

$b^x = b^{(x \% \phi(m))} \pmod m$

然后幂次都变为$0$

就直接加起来$模2判断一下就好了$

$但是没有考虑到0^0次的问题$

$在这里如果b % 2 == 0, 那么带b的项都为0$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 100010
 5 int b, k, a[N];
 6
 7 int main()
 8 {
 9     while (scanf("%d%d", &b, &k) != EOF)
10     {
11         int res = 0;
12         for (int i = 1; i <= k; ++i) scanf("%d", a + i);
13         for (int i = 1; i <= k; ++i)
14             res = (res + a[i] % 2) % 2;
15         if (b % 2 == 0) res = a[k];
16         puts(res % 2 ? "odd" : "even");
17     }
18     return 0;
19 }

B. Tape

签.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 100010
 5 int n, m, k;
 6 int b[N];
 7
 8 int main()
 9 {
10     while (scanf("%d%d%d", &n, &m, &k) != EOF)
11     {
12         --k;
13         for (int i = 1; i <= n; ++i) scanf("%d", b + i);
14         int res = b[n] - b[1] + 1;
15         priority_queue <int> pq;
16         for (int i = 2; i <= n; ++i) pq.push(b[i] - b[i - 1] - 1);
17         while (!pq.empty() && k--)
18         {
19             res -= pq.top();
20             pq.pop();
21         }
22         printf("%d\n", res);
23     }
24     return 0;
25 }

C. Meaningless Operations

Solved.

题意:

给出一个数$a$

$定义(f(a) = max_{1 <= b < a} gcd(a \oplus b, a \& b))$

给出$f(a)$

思路:

考虑$gcd(x, 0) = x$

那么我们构造$(a \& b) = 0, 并且 (a \oplus b)最大即可$

$对于2^x - 1 这种东西是没法构造的$

$考虑这样的数不多,提前打表即可$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int q, x;
 5 map <int, int> ans;
 6
 7 int solve(int x)
 8 {
 9     if (ans.find(x) != ans.end()) return ans[x];
10     int res;
11     for (int i = 24; i >= 0; --i) if (((x >> i) & 1))
12     {
13         res = (1 << (i + 1)) - 1;
14         break;
15     }
16     return ans[x] = res;
17 }
18
19 int main()
20 {
21 ans[1] = 1,
22 ans[3] = 1,
23 ans[7] = 1,
24 ans[15] = 5,
25 ans[31] = 1,
26 ans[63] = 21,
27 ans[127] = 1,
28 ans[255] = 85,
29 ans[511] = 73,
30 ans[1023] = 341,
31 ans[2047] = 89,
32 ans[4095] = 1365,
33 ans[8191] = 1,
34 ans[16383] = 5461,
35 ans[32767] = 4681,
36 ans[65535] = 21845,
37 ans[131071] = 1,
38 ans[262143] = 87381,
39 ans[524287] = 1,
40 ans[1048575] = 349525,
41 ans[2097151] = 299593,
42 ans[4194303] = 1398101,
43 ans[8388607] = 178481,
44 ans[16777215] = 5592405,
45 ans[33554431] = 1082401;
46     while (scanf("%d", &q) != EOF)
47     {
48         while (q--)
49         {
50             scanf("%d", &x);
51             printf("%d\n", solve(x));
52         }
53     }
54     return 0;
55 }

D. Jongmah

Upsolved.

题意:

有一些数字,三个相同的数字消去

三个连续的也可以消去

求最多消去多少组

思路:

$dp[i][j][k] 表示到第i大的数, 第i - 2大的数还余了j个, 第i - 1个数还余了k个$

$的最大消去的组数$

$转移的时候注意能跟前面的余数组成连续的就组成连续的$

$因为和前面余数组成连续的只需要出一张牌就获得1的贡献$

$如果消去当前三张相同的需要三张牌,至少是不会亏的$

$注意转移的时候要把前面的余数也剪掉$

$再考虑每张牌最多出5张和前面和后面的其他牌组成连续的$

$那么j, k的状态只有6个$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define ll long long
 5 #define N 1000010
 6 int n, m, a[N];
 7 ll f[2][6][6];
 8
 9 int main()
10 {
11     while (scanf("%d%d", &n, &m) != EOF)
12     {
13         memset(a, 0, sizeof a);
14         memset(f, -1, sizeof f);
15         for (int i = 1, x; i <= n; ++i)
16         {
17             scanf("%d", &x);
18             ++a[x];
19         }
20         if (m <= 2)
21         {
22             printf("%d\n", a[1] / 3 + a[2] / 3);
23             continue;
24         }
25         ll res = 0;
26         for (int i = 0; i < 6; ++i)
27             for (int j = 0; j < 6; ++j)
28                 if (a[1] >= i && a[2] >= j)
29                     f[2 & 1][i][j] = (a[1] - i) / 3 + (a[2] - j) / 3;
30         //for (int i = 1; i <= m; ++i) printf("%d%c", a[i], " \n"[i == m]);
31         for (int i = 3; i <= m; ++i)
32         {
33             for (int j = 0; j < 6; ++j)
34                 for (int k = 0; k < 6; ++k)
35                     f[i & 1][j][k] = -1;
36             for (int j = 0; j < 6; ++j)
37             {
38                 for (int k = 0; k < 6; ++k) if (f[(i & 1) ^ 1][j][k] != -1)
39                 {
40                     for (int o = 0; o < 6; ++o)
41                     {
42                         int need = min(j, min(a[i] - o, k));
43                         ll base = f[(i & 1) ^ 1][j][k];
44                         if (a[i] >= o)
45                         {
46                             for (int w = 0; w <= need; ++w)
47                                 f[i & 1][k - w][o] = max(f[i & 1][k - w][o], base + (a[i] - o - w) / 3 + w);
48                         }
49                     }
50                 }
51             }
52             //for (int j = 0; j < 3; ++j)
53             //    for (int k = 0; k < 3; ++k)
54             //        printf("%d %d %d %lld\n", i, j, k, f[i][j][k]);
55         }
56         for (int i = 0; i < 6; ++i)
57             for (int j = 0; j < 6; ++j)
58                 res = max(res, f[m & 1][i][j]);
59         printf("%lld\n", res);
60     }
61     return 0;
62 }

E. Magic Stones

Upsolved.

题意:

有一个数字序列$A[], 每次可以选择一个i \in [2, n - 1]$

$使得 A[i] = A[i + 1] + A[i - 1] - A[i]$

问能否经过一些这样的操作,使得$A[] -> B[]$

思路:

我们令$d[i] = A[i + 1] - A[i]$

我们考虑$上述的那个操作$

$d_i = A[i + 1] - (A[i + 1] + A[i - 1] - A[i]) = A[i] - A[i - 1] = d_{i - 1}$

同理

$d_{i - 1} = d_{i}$

我们注意到,这个操作变成了交换元素

$那么把B[]数组也变成差分数组,如果两个差分数组通过任意交换后相同$

$那么原序列通过以系列操作也可以相同$

$即排个序判断是否相同即可,再注意一下第一个是否相同$

F. Nearest Leaf

Upsolved.

题意:

给出一个树, 询问$离v节点最近叶子节点的距离$

注意给出的点序是$DFS序$

思路:

将询问离线,令根为$1$

$考虑如果询问1号点,那么跑一遍DFS,将所有点的距离丢进线段树$

$查最小值即可$

那么对于一个点$x$

我们考虑从线段树里面维护的距离是到它父亲$y的距离$

$那么我们要把这个距离转变成到x的距离$

$可以发现,它子树内的点都需要减去一条边,就是它父亲到它那条边$

$它子树外的点都需要加上一条边,是它父亲到它那条边$

$子树内的点是连续的,所以可以在线段树上操作$

原文地址:https://www.cnblogs.com/Dup4/p/10355916.html

时间: 2024-07-28 13:21:16

Codeforces Global Round 1的相关文章

Codeforces Global Round 1 (A-E题解)

Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^(k-1)+a2*b^(k-2)+...+ak*b^0的奇偶性. 题解: 暴力求模2意义下的值就好了. 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5+5; int

【手抖康复训练1 】Codeforces Global Round 6

[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思路手抖过不了样例,C题秒出思路手抖过不了样例*3 D题 手抖 过的了样例 ,调了1h,赛后发现变量名写错了,改一个字符就能AC... 题目等补完题一起放上来QAQ 原文地址:https://www.cnblogs.com/ttttttttrx/p/12110199.html

Frets On Fire --- 2019 Codeforces Global Round 2 Problem D

原题:https://codeforces.com/contest/1119/problem/D 题意大概是一个n行1e18列的矩阵,其中每行第一个数为s[i],剩下的数每行依次以1的速度递增.就是说,矩阵元素 a[i][j] = s[i] + j .有q个询问,每个询问有两个参数l,r,求矩阵第l列到第r列(所有行)一共出现了几个不同的数. 这道题首先要先想到,两个参数 [l,r] 其实等价于一个参数 [0,r-l] ,也就是说矩阵第0~r-l行出现的数字的个数其实和第l-r行出现的个数是一样

[Codeforces]Codeforces Global Round 1

A - Parity 题意 给定一个$b$进制数,要求输出它在十进制下是奇数还是偶数. 分析 花了我略多的时间,首先题目中给的数字范围很大,不能直接转化为10进制. 分析性质,发现只有奇数乘奇数还是奇数,其他都是偶数. 对奇数进制和偶数进制分类讨论. 偶数进制看最低位的奇偶性,如果是奇数那么这个数就是奇数,不然是偶数. 奇数进制看每一位上奇数的个数,如果是奇数个奇数就是奇数,不然是偶数. 代码 1 #include <bits/stdc++.h> 2 using namespace std;

【 Codeforces Global Round 1 B】Tape

[链接] 我是链接,点我呀:) [题意] x轴上有m个连续的点,从1标号到m. 其中有n个点是特殊点. 让你用k段区间将这n个点覆盖. 要求区间的总长度最小. [题解] 一开始假设我们需要n个胶带(即包含每一个点) 然后因为k<=n 所以可能胶带不够用. 那么就得一个胶带跨过两个点. 怎么选择最好呢? 可以把b[i]-b[i-1]-1处理出来排个序. (优先取较小的花费) 然后取前n-k个累加和sum. 因为每取一个就少用一段胶带. 然后sum+n就是答案了 [代码] import java.i

【Codeforces Global Round 1 C】Meaningless Operations

[链接] 我是链接,点我呀:) [题意] 给你一个a 让你从1..a-1的范围中选择一个b 使得gcd(a^b,a&b)的值最大 [题解] 显然如果a的二进制中有0的话. 那么我们就让选择的b的二进制中对应的位置为1 剩下全为0就好 这样a的二进制全都变成1之后就是答案了(gcd的右边是0). 但是如果a的二进制里面全是1的话. 就没办法这么构造了 这里有两种情况. ①.1的个数是偶数 那么就101010这样构造 另外一个数就是010101 答案就是010101转换成十进制 ②.1的个数是奇数

【Codeforces Global Round 1 A】Parity

[链接] 我是链接,点我呀:) [题意] 给你一个k位数b进制的进制转换. 让你求出来转成10进制之后这个数字是奇数还是偶数 [题解] 模拟一下转换的过程,加乘的时候都记得对2取余就好 [代码] import java.io.*; import java.util.*; public class Main { static int N = (int)1e5; static InputReader in; static PrintWriter out; static int b,k; static

[codeforces]Codeforces Global Round 1 F. Nearest Leaf

题解:  语文题????  上面说的一段代码 告诉你的是  节点编号顺序与dfs序顺序一致  也就是你  dfs序以后编号就是[1,n]  根据这个特性  那么我们只需要维护每个叶子节点到查询v的距离即可  那么我们只需要离线所有查询 然后对子树修改即可   用线段树来维护区间加和区间最小值就行 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #inc

Codeforces Global Round 1 自闭记

A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long char getc(){char c=getchar();while ((c<'A'||c>'Z')&&a