Codeforces Round 919 (Div. 2)题解(A-E)

2024-02-16 20:44
文章标签 codeforces round div 题解 919

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

https://codeforces.com/contest/1920

image-20240216183012606

A Satisfying Constraints

链接:A - Satisfying Constraints

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{int T;cin >> T;while(T--){int n;scanf("%d", &n);vector<int> eq;int a1 = 1, a2 = 1e9 + 2;for(int i = 1; i <= n; i++){int x, y;scanf("%d%d", &x, &y);if(x == 1){a1 = max(a1, y);}else if(x == 2){a2 = min(a2, y);}else{eq.push_back(y);}}if(a2 < a1) puts("0");else{int sub = 0;for(int x : eq){if(x >= a1 && x <= a2){sub++;}}printf("%d\n", a2 - a1 + 1 - sub);}}return 0;
}

B Summation Game

链接:B - Summation Game

代码

#include <bits/stdc++.h>
using namespace std;
int n, k, x;
const int N = 3e5 + 2;
int a[N], s[N];
int main()
{   int T;cin >> T;while (T--){int ans = -0x3f3f3f3f;scanf("%d%d%d", &n, &k, &x);for(int i = 1; i <= n; i++){scanf("%d", a + i);}sort(a + 1, a + 1 + n);s[0] = 0;for(int i = 1; i <= n; i++){s[i] = s[i - 1] + a[i];}for(int i = 0; i <= min(n, k); i++){int r = n - i;if(r <= 0) {ans = max(ans, 0);}else{int m = r - x;m = max(0, m);int tmp = s[m] - (s[r] - s[m]);ans = max(ans, tmp);}}printf("%d\n", ans);}return 0;
}

C Partitioning the Array

链接:C - Partitioning the Array

题意

艾伦有一个数组 a1,a2,…,an𝑎1,𝑎2,…,𝑎𝑛 。对于每个是 n𝑛 除数的正整数 k𝑘 ,艾伦都会做如下运算:

  • 他将数组分割成长度为 k𝑘 的 nk𝑛𝑘 个互不相交的子数组。换句话说,他将数组划分为以下子数组:
    [a1,a2,…,ak],[ak+1,ak+2,…,a2k],…,[an−k+1,an−k+2,…,an]

  • 如果存在某个正整数 𝑚 ( 𝑚≥2 ),使得他将数组中的每个元素除以 𝑚 后的余数都替换为该元素,则所有子数组都相同,则艾伦得一分。

帮助艾伦找出他将获得的分数。

思路

对于两个数字: x x x y y y,设其在模m的情况下相等,那么会有 x m o d m ≡ y m o d m x \bmod m \equiv y \bmod m xmodmymodm,即有 ( x − y ) ≡ 0 ( m o d m ) (x-y) \equiv 0 \pmod m (xy)0(modm)

当且仅当m为 x − y x-y xy 的因数的时候,在模m意义下,两个数字相等。


由于每组的对应元素在模 m m m 意义下都相等,所以 m 应该为每一组元素两两之间的gcd


补充:当一个参数为零时,最大公约数(Greatest Common Divisor,gcd)定义为另一个参数的绝对值。因此,当一个参数为零时,gcd(0, x)等于x的绝对值。

代码

#include <bits/stdc++.h>
using namespace std;
int n;
typedef long long ll;
const int N = 2e5 + 30;
int a[N];
int solve(int d)
{int g = 0;for(int i = 1; i <= n - d; i++){g = __gcd(g, abs(a[i] - a[i + d]));}//如果为0,那么表示d为n的情况return g != 1;
}
int main()
{int T;cin >> T;while(T--){int ans = 0;scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d", a + i);for(int i = 1; (ll)i*(ll)i <= (ll)n; i++){if(n % i == 0){if(i * i == n){ans += solve(i);}else{ans += solve(i);ans += solve(n / i);}}}printf("%d\n", ans);}return 0;
}

D Array Repetition

链接:D - Array Repetition

思路

依次记录每一次操作之后的数组总长度。

在给定需要求得的位置时,确定其是在那一次操作引入的:

  • 若为add操作,那么直接得出值
  • 若为复制操作,那么递归求取该位置在复制前位置上的值

由于复制操作会使得位置坐标至少减少一半,所以在时间复杂度足够优秀。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5;
int n, q;
vector<__int128> qu;
int val[N];
int mul[N];
int solve(int x){while(x >= 0){int idx = lower_bound(qu.begin(), qu.end(), x) - qu.begin();if(val[idx] != -1){return val[idx];}else{x = (x - 1) % (qu[idx] / mul[idx]) + 1;}}
}signed main()
{int T;cin >> T;while(T--){qu.clear();__int128 len = 0;bool valid = true;scanf("%lld%lld", &n, &q);for(int i = 0; i < n; i++){int x, y;scanf("%lld%lld", &x, &y);if(x == 1){len++;val[i] = y;}else{len *= (y + 1);val[i] = -1;mul[i] = (y+1);}if(valid)//!!!!!!!!!!!qu.push_back(len);if(len > (__int128)1e18){valid = false;}}for(int _ = 1; _ <= q; _++){int x;scanf("%lld", &x);printf("%lld ", solve(x));}puts("");}return 0;
}

E Counting Binary Strings

链接:E- Counting Binary Strings

题意

如果二进制字符串 ‡ ^\ddagger 的子串 † ^\dagger 恰好包含一个 1,Patrick 就称该子串为好字符串。

帮助帕特里克计算二进制字符串 s s s 的个数,使得 s s s 包含恰好 n n n 个好子串,并且没有长度严格大于 k k k 的好子串。注意,子串是根据它们在字符串中的位置来区分的,因此如果 s = s = s= 1010 时,应同时计算 10 的出现次数。

† ^\dagger 如果从 b b b 中删除开头的几个(可能是零个或全部)字符和结尾的几个(可能是零个或全部)字符就可以得到 a a a ,那么字符串 a a a 就是字符串 b b b 的子串。

‡ ^\ddagger 二进制字符串是指只包含 0 和 1 字符的字符串。

思路

模型转化

进行演算:
00001 ⏟ a 1 ⁣ ⁣ ⁣  ⁣ 0001 ⏟ a 2 ⁣ ⁣ ⁣  ⁣ 00000001 ⏟ a 3 ⁣ ⁣ ⁣  ⁣ 0001 ⏟ a 4 ⁣ ⁣ ⁣  ⁣ 000 ⏟ a 5 \underbrace{00001}_{a_1} \! \! \! \, \underbrace{ \; \, \! 0001}_{a_2} \! \! \! \, \underbrace{ \; \, \! 00000001}_{a_3} \! \! \! \, \underbrace{ \; \, \! 0001}_{a_4} \! \! \! \, \underbrace{ \; \, \! 000}_{a_5} a1 00001a2 0001a3 00000001a4 0001a5 000

在这个例子中,好子串的数目是 a 1 a 2 + a 2 a 3 + a 3 a 4 + a 4 a 5 a_1 a_2 + a_2 a_3 + a_3 a_4 + a_4 a_5 a1a2+a2a3+a3a4+a4a5。我们可以为任何字符串 s s s 创建这样的数组,而 s s s 的好子串数就是数组中相邻元素的乘积之和。

我的理解:

对于每一个1,我们要计算其的贡献。

不妨假设左边有n个连续的零,右边有m个连续的零,其所产生的好串的数目为 ( n + 1 ) ⋅ ( m + 1 ) (n + 1) \cdot(m + 1) (n+1)(m+1)

对于第一个1,其 m+1 与第二个1的 n+1 是相同的,均为4。所以,可以进行转化为一个数组的相邻项的乘积相加。

进行DP

状态为 d p i , j = number of arrays with sum i and last element j dp_{i,j} = \text{number of arrays with sum i and last element j} dpi,j=number of arrays with sum i and last element j

得到初步的转移等式: d p i , j = ∑ p = 1 k − j + 1 d p i − j ⋅ p , p dp_{i, j} = \sum_{p=1}^{k-j+1}{dp_{i - j \cdot p,p}} dpi,j=p=1kj+1dpijp,p

k-j+1是为了限制 并且没有长度严格大于 k k k 的好子串

但是其时间复杂度不够优秀。可以进行一个优化,即求和的过程中,p最多到达 ⌊ i (总和) j (数组中当前的最后一个元素) ⌋ \lfloor \frac{i(总和)}{j(数组中当前的最后一个元素)} \rfloor j(数组中当前的最后一个元素)i(总和),若超过这个值,仅仅 p ⋅ j p \cdot j pj 便超过了i,显然没有意义。


如此优化之后,结合常识:
n 1 + n 2 + ⋯ + n n = O ( n log ⁡ n ) \frac{n}{1} + \frac{n}{2} + \cdots + \frac{n}{n} = O(n\log n) 1n+2n++nn=O(nlogn)
便可以使得时间复杂度合格, O ( n 2 log ⁡ 2 n ) O(n^2 \log_2n) O(n2log2n)

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 3000;
int dp[N][N];
const int mod = 998244353;
int n, k;
void cleanse(){for(int i = 0; i <= n; i++){for(int j = 0; j <= n; j++){dp[i][j] = 0;}}for(int i = 0; i <= n; i++){// 更确切为 1 到 kdp[0][i] = 1;}
}
int main()
{int T;cin >> T;while(T --){scanf("%d%d", &n, &k);cleanse();for(int sum = 1; sum <= n; sum++){for(int cur = 1; cur <= k; cur++){for(int j = 1; j <= (sum / cur) && j + cur - 1 <= k; j++){dp[sum][cur] = ((long long)dp[sum][cur] + dp[sum - j * cur][j])%mod;}}}int ans = 0;for(int i = 1; i <= k; i++){ans = (ans + dp[n][i]) % mod;}printf("%d\n", ans);}return 0;
}

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



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

相关文章

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

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

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

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

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

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述