codeforces一些题目思路复盘

codeforces round 919 dv2 C Partitioning the Array

大致题意,对于n约数i,我们把原数组分成\frac{n}{i}份,并且每份中有i个元素,对于每个分组情况,如果存在一个数m使得数组中元素modm后使得每个部分的数组完全相同,如果存在那么ans ++求ans

这是一道数论题,数论题的关键在于将数学问题用数学公式表示出来,现在考虑如果存在一个数组a_1a_2a_3a_4....a_n是否存在一个整数m使得数组amodm后所有元素相同

对于这个简化的问题首先列出数学公式 对于i\epsilon[1, n]j\epsilon[1, n] i \neq j 有 a_i\equiv a_j modm

对这个同余式子移项后可得到|a_i - a_j|\equiv 0modm,对于这个式子我们得到这样一个结论|a_i - a_j|是可以整除m的。当然m不能为1,现在把这个式子拓展到整个数组,那么就有了所有相邻元素相减的绝对值都应该整除m,并且m不为1,换句话说这些数两两不互质。当然m的最大值就是这些数的gcd了(codeforces round991 div3 F Maximum modulo equality)。

现在再回到这个问题上,这个问题就相当于这个m必须同时满足很多个数组(\frac{n}{i}个,每个子数组中的元素)每个数组求出gcd中,再将这些gcd求总共gcd,只要gcd不为1,就说明ans可以++。当然这里也涉及到时间复杂度的计算,首先的约数预处理O(n\sqrt{n})最外层的for是约数个数,数据范围内最大的约数个数为168个,总之约数的个数都很小。紧接着的两重循环不大会算,但是感觉可以过:(

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
const int N = 2e5 + 10;int gcd(int a, int b) {return b? gcd(b, a % b): a;
}void solve() {int n;cin >> n;vector<int> a(n + 1);for(int i = 1; i <= n; i ++ ) cin >> a[i];vector<int> divi;for(int i = 1; i <= n / i; i ++ ) {if(n % i == 0) {divi.push_back(i);if(n / i != i) divi.push_back(n / i);}}int ans = 1;for(auto t: divi) {//168bool ok = true;if(t == n) continue;else {vector<int> alls;for(int i = 1; i <= t; i ++ ) {int _gcd = -1;for(int j = i + t; j <= n; j += i ) {if(_gcd == -1) _gcd = abs(a[j] - a[j - t]);else _gcd = gcd(_gcd, abs(a[j] - a[j - t]));}alls.push_back(_gcd);}int _gcd = -1;for(auto t: alls) {if(_gcd == -1) _gcd = t;else _gcd = gcd(t, _gcd);}if(_gcd == 1) ok = false;}if(ok) ans ++;}cout << ans << "\n";
}int main() {ll t;cin >> t;while(t -- ) solve();return 0;
}

codeforces round914div2 C array game

这道题是个tips题,注意到当k大于3时答案总是0,在遇到无从下手的题目时一定要试着去寻找一些特判情况,将答案简化

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
const ll INF = 1e18;void solve() {ll n, k;cin >> n >> k;vector<ll> a(n + 1);ll minv = INF;for(int i = 1; i <= n; i ++ ) {cin >> a[i];minv = min(minv, a[i]);}sort(a.begin() + 1, a.end());ll ans = INF;if(k > 2) {cout << "0\n";return;} else if(k == 1) {for(int i = 1; i <= n; i ++ ) {for(int j = 1; j <= n; j ++ ) {if(i == j) continue;ans = min(ans, abs(a[i] - a[j]));}}} else if(k == 2) {for(int i = 1; i <= n; i ++ ) {for(int j = i + 1; j <= n; j ++ ) {if(i == j) continue;ll del = a[j] - a[i];int l = 1, r = n;while(l < r) {int mid = l + r >> 1;if(a[mid] >= del) r = mid;//找到第一个大于等于del的数else l = mid + 1;}ans = min(ans, abs(a[l] - del));ans = min(ans, abs(a[l - 1] - del));}}}cout << min(ans, minv) << "\n";
}int main() {ll t;cin >> t;while(t -- ) solve();return 0;
}

D set to max

题目大意:给出两个数组,a,b,每次可以从a中任意选择一段区间,并且把区间中元素赋值成区间最大值,easy version和hard version的区别就在于数据范围,有经验的话会立刻明白这个数据范围的作用就是限制求区间最值时的方式,时间复杂度O(n^2)允许的话可以直接暴力求解,反之则可以用线段树维护。现在去思考如何解决这个问题:为了方便我们对数据进行处理,把目标区间取出来是必要的。现在考虑方案的可行性,下述区间的表述都是取出来的区间段,即对于一个区间段的任意l,r,满足b[l] = b[r]。如果a中该区间段最大值大于了该区间中b的值(设为x),那么直接判负,因为较大数值会覆盖较小的数值.。同样的如果想要赋值成x,就要保证a数组中存在x,并且在达到x之前没有比x更大的数。这样就结束了吗,上文中提到了,较大值会覆盖最小值,倘若在枚举到当前区间前维护的区间的x比该区间的x要大,并且恰好我这个区间所需要的值被覆盖掉了,那么会导致可行的方案被判否,因此要贪心的以x值较小的区间开始维护,并且在以后的维护中,如果在a中的x必须跨越先前已经维护过的区间,那么答案就会被判否(因为会将以前维护好的覆盖掉)

现在思路就明朗了,时间复杂度O(nlogn)整体可控

代码:
 

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
const int INF = 0x3f3f3f3f;void solve() {int n;cin >> n;vector<int> a(n + 2), b(n + 1);for(int i = 1; i <= n; i ++ ) cin >> a[i];for(int i = 1; i <= n; i ++ ) cin >> b[i];map<int, int> ma;a[0] = a[n + 1] = INF;vector<int> L(n + 1), R(n + 1);for(int i = 1; i <= n; i ++ ) {if(ma[b[i]] == 0) L[i] = 0;else L[i] = ma[b[i]];ma[a[i]] = i;}ma.clear();for(int i = n; i >= 1; i -- ) {if(ma[b[i]] == 0) R[i] = n + 1;else R[i] = ma[b[i]];ma[a[i]] = i;}struct node {int l, r, val, tag;bool operator < (const node &W) {return val < W.val;}};vector<node> tr(n * 4 + 1);auto pushup = [&](int u) {tr[u].val = max(tr[u << 1].val, tr[u << 1 | 1].val);};function<void(int, int, int)> build = [&](int u, int l, int r) {tr[u].l = l, tr[u].r = r;if(l == r) return;int mid = l + r >> 1;build(u << 1, l, mid);build(u << 1 | 1, mid + 1, r);};function<void(int, int)> insert = [&](int u, int pos) {if(tr[u].l == tr[u].r && tr[u].l == pos) tr[u].val = a[pos];else {int mid = tr[u].l + tr[u].r >> 1;if(mid >= pos) insert(u << 1, pos);if(mid < pos) insert(u << 1 | 1, pos);pushup(u);}};function<int(int, int, int)> query = [&](int u, int l, int r) {if(tr[u].l >= l && tr[u].r <= r) return tr[u].val;else {int res = 0;int mid = tr[u].l + tr[u].r >> 1;if(mid >= l) res = query(u << 1, l, r);if(mid < r) res = max(res, query(u << 1 | 1, l, r));return res;}};build(1, 1, n);for(int i = 1; i <= n; i ++ ) insert(1, i);vector<node> st(4 * n + 1);function<void(int, int, int)> build1 = [&](int u, int l, int r) {st[u].l = l, st[u].r = r;if(l == r) return;int mid = l + r >> 1;build1(u << 1, l, mid);build1(u << 1 | 1, mid + 1, r);};auto pushup1 = [&](int u) {st[u].val = st[u << 1].val | st[u << 1 | 1].val;    };auto pushdown = [&](int u) {st[u << 1].val |= st[u].tag;st[u << 1].tag |= st[u].tag;st[u << 1 | 1].val |= st[u].tag;st[u << 1 | 1].tag |= st[u].tag;st[u].tag = 0;};function<void(int, int, int)> insert1 = [&](int u, int l, int r) {if(st[u].l >= l && st[u].r <= r) {st[u].val = 1;st[u].tag = 1;} else {pushdown(u);int mid = st[u].l + st[u].r >> 1;if(mid >= l) insert1(u << 1, l, r);if(mid < r) insert1(u << 1 | 1, l, r);pushup1(u);}};function<int(int, int, int)> query1 = [&](int u, int l, int r) {if(st[u].l >= l && st[u].r <= r) return st[u].val;else {int res = 0;int mid = st[u].l + st[u].r >> 1;if(mid >= l) res = query1(u << 1, l, r);if(mid < r) res |= query1(u << 1 | 1, l, r);return res;}};build1(1, 1, n);vector<node> pos;int i = 1, j = 1;while(i <= n && j <= n) {while(j <= n && b[i] == b[j]) j ++;pos.push_back({i, j - 1, b[i]});i = j;}//cout << L[4] << " ";sort(pos.begin(), pos.end());for(int k = 0; k < pos.size(); k ++ ) {auto t = pos[k];int l = t.l, r = t.r, x = t.val;//cout << l << " " << r << " " << x << "\n";int max_val = query(1, l, r);if(max_val > x) {cout << "NO\n";return;}if(max_val == x) {insert1(1, l, r);continue;}bool ok1 = false;bool ok2 = false;if(a[L[l]] == x && !query1(1, L[l], l) && (query(1, L[l], l) == x)) ok1 = true;if(a[R[r]] == x && !query1(1, r, R[r]) && (query(1, r, R[r]) == x)) ok2 = true;if(!ok1 && !ok2) {cout << "NO\n";return;} else {/*for(int i = l; i <= r; i ++ ) insert1(1, i);*/insert1(1, l, r);}}//cout << query1(1, 1, 2) << " ";cout << "YES\n";
}int main() {int t;cin >> t;while(t -- ) solve();return 0;
}

codeforces round 932 div2 C find a mine

这是一道交互题,这道题这道题启示我到一个点的曼哈顿距离相等的所有点的路径是个菱形(如果没有超过图的边界的话)

D1. XOR Break — Solo Version

题目大意:对于x我们可以将x设为y或者xXORy并且满足y < x并且xXory < x问是否可以将x变成m(m < x)

数据范围很大,并且有xor操作,直接考虑拆位

现在似乎仍然无从下手,那么试着挖掘一些隐含在题目中的性质

m小于x试着考虑一下这个条件的性质:

容易得到,如果xy满足小于关系那么有

x: same 1 ??????

m:same 0 ??????

从高位起第一位不同的二进制表示,x为1,m为0

再考虑如果x Xor y < x要满足什么条件

x:             same 1 ??????

y          :  00000 1 ??????

m         :  same   0 ??????(x xor y = m)

其实这里可以注意到如果same存在1的话,那么后面的????填什么都可以因为y肯定比x小并且m本来就比x小,现在要讨论的情况就是same全为0的情况。如果m的?号位为0的话,那么x和y的?号位要相同,不是0就是1,反之?号位不同,也就是说,如果在same 1以后的二进制表示位中,如果m中出现的第一个1对应的x中二进制中表示位是1的话,那么我们同样可以将x转化为m,反之就证明当前的y比x要小,不满足题意,这时候我们要考虑是否可以借助一个中间值转化一下,使得这一位的值变成1(借位),借位只能向1借,并且不能same后面的那位1实际上是不能动的,这里可以手动模拟一下,也就是说,如果在same1后面的二进制位到该位之间x二进制表示位为1的话,我们就可以借助这个中间值将其转化为上述的情况。(可以找个较小的数值模拟一下)

代码:

#include <bits/stdc++.h>
using namespace std;typedef long long ll;void solve() {ll n, m;cin >> n >> m;bool ok = 0;ll pos = -1;for(ll i = 62; i >= 0; i -- ) {if(n >> i & 1) {if(!(m >> i & 1)) {pos = i;break;}}if(n >> i & 1) ok = true;}//cout << pos << "LL";if(ok) {cout << "1\n";cout << n << " " << m << "\n";} else {bool flag = false;for(ll i = pos - 1; i >= 0; i -- ) {if(m >> i & 1) {if(n >> i & 1) {flag = true;break;}if(!(n >> i & 1)) break;}}if(flag) {cout << "1\n";cout << n << " " << m << "\n";} else {/*0 0 0 0 0 1 a b c 00 0 0 0 0 1 a b c 10 0 0 0 0 0 0 0 0 1*/ll pos1 = -1;for(ll i = pos - 1; i >= 0; i -- ) {if(m >> i & 1) break;if(n >> i & 1) {pos1 = i;break;}}if(pos1 == -1) cout << "-1\n";else {cout << "2\n";ll res = n;ll now = 1ll << pos;for(ll i = 62; i >= pos; i -- ) {res -= (n >> i & 1) * (1ll << i);}for(ll i = pos1 - 1; i >= 0; i -- ) {if((m >> i & 1) && !(n >> i & 1)) {res += 1ll << i;break;}}cout << n << " " << res << " " << m << "\n";}}}
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);ll t;cin >> t;while(t -- ) solve();return 0;
}

codeforces round 991 div3 G

题目大意,从一颗树中删除一条链,找到删除后联通块数量的最大值

树类的问题,直接考虑dfs,树形dp

首先有一个很重要的性质,路径一定要尽可能多的删(除了叶子节点),并且每个点的贡献与这个点的临边数量有关,其实思考一下就是树的直径,只不过把边权换成了点权...

这里说一下树的直径:

代码:
 

#include <bits/stdc++.h>
using namespace std;typedef long long ll;void solve() {int n;cin >> n;vector<vector<int>> adj(n + 1);for(int i = 2; i <= n; i ++ ) {int u, v;cin >> u >> v;adj[u].push_back(v);adj[v].push_back(u);}vector<int> dp(n + 1);int ans = 0;function<void(int, int)> dfs = [&](int u, int fa) {int tot = adj[u].size();dp[u] = max(0, tot - 2);int fir = -1, sec = -1;bool flag = true;for(auto t: adj[u]) {if(t == fa) continue;flag = false;dfs(t, u);dp[u] = max(dp[u], tot - 2 + dp[t]);if(dp[t] >= fir) {sec = fir;fir = dp[t];} else if(dp[t] >= sec) {sec = dp[t];}int res = max(0, fir) + max(0, sec);if(tot == 1) res ++;else if(tot > 2) res += tot - 2;ans = max(res, ans);}if(flag) dp[u] = 1;};if(n == 2) cout << "1\n";else {dfs(1, 1);cout << ans << "\n";}
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t;cin >> t;while(t -- ) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch 简介

一、什么是 ElastcSearch&#xff1f; ElasticSearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎。 1.1 ElasticSearh 的基本术语概念 index 索引 索引类似与 mysql 中的数据库&#xff0c;ES 中的索引是存储数据的地方&#xff0c;包含了一堆有相似结构的文档数据…

解决 Git 默认不区分文件名大小写的问题

不得不说 Git 默认不区分文件名大小写真是一个大坑&#xff0c;由于之前的项目目录比较乱&#xff0c;项目下的文件夹命名都不规范&#xff0c;这两天一直在整理&#xff0c;然后今天从服务器将项目重新 clone 下来后发现&#xff0c;之前将所有文件名首字母改成大写的改动全部…

Python自动化操作文档系列

在忙碌的工作中&#xff0c;你是否渴望偶尔的轻松时刻&#xff1f;Python自动化操作文档系列专题文章为你带来全新的 “摸鱼神器”。Python以其高效灵活的特性&#xff0c;能让繁琐任务自动完成&#xff0c;为你争取片刻悠闲。从简单的脚本到复杂的自动化流程&#xff0c;本系列…

CSS中相对、固定、绝对及粘性定位的应用场景

在CSS中&#xff0c;不同的定位方式&#xff08;相对定位、固定定位、绝对定位和粘性定位&#xff09;各自有其特定的使用场景。以下是这些定位方式的详细说明和使用场景&#xff1a; 1. 相对定位&#xff08;Relative Positioning&#xff09; 使用场景&#xff1a; 微调元…

Please activate LaTeX Workshop sidebar item to render the thumbnail of a PDF

Latex代码中使用pdf图片&#xff0c;无法预览&#xff0c;提示&#xff1a; Please activate LaTeX Workshop sidebar item to render the thumbnail of a PDF 解决办法&#xff1a; 点击左边这个刷新下即可

openEuler centOS 统信UOS 配置ip的方式。

前言: 不同的Linux发行版&#xff0c;其基础命令基本相同。 配置网络的具体方式缺可能有多种方式。经过实操&#xff0c;发现openEuler centOS 统信UOS这三种操作系统的配置网络方式一样&#xff0c;所以记录下操作步骤。 在openEuler、centOS、统信UOS上配置静态IP地址&…

测试工程师的职业规划

测试人员在管理上的发展 基层测试管理者&#xff1a;测试组长 工作内容&#xff1a;安排小组工作&#xff0c;提升小组成员测试能力&#xff0c;负责重要的测试工作。 负责对象&#xff1a;版本&#xff0c;项目 中层测试管理者&#xff1a;测试经理 负责对象&#xff1…

Linux系统下多任务管理器:screen使用指南

文章目录 安装快速入门启动Screen会话创建和管理窗口退出和恢复会话 高级功能多用户支持日志记录复制粘贴模式自定义配置 在Linux和类Unix系统的世界里&#xff0c;命令行是用于与系统交互的主要方式之一。然而&#xff0c;当涉及到远程服务器管理、长时间运行的任务或者同时处…

Android系统卡启动问题排查

Android系统启动正常来说会涉及到如下几个过程&#xff1a; 引导加载程序&#xff08;Bootloader&#xff09;Linux内核&#xff08;Kernel&#xff09;&#xff0c;负责硬件抽象、内存管理、进程管理、网络堆栈等init进程 init进程读取init.rc配置文件&#xff0c;用于启动各…

C缺陷与陷阱 — 8 编译与链接

目录 1 程序的编译过程 2 动态链接的优缺点 2.1 动态链接的优点 2.2 动态链接的缺点 2.3 只使用动态链接 3 函数库链接的5个特殊秘密 4 警惕Interpositioning 5 产生链接器报告文件 1 程序的编译过程 程序的编译过程是将源代码转换成计算机可以执行的机器代码的过程。…

Harmony Next开发Navigation页面跳转

概述 Harmony Next开发Navigation页面跳转 知识点 Navigation通过NavPathStack路由跳转Navigation以弹窗的方式打开NavDestination页面Menu配置 组件 NavTest Entry Component struct NavTest {Provide pageInfos: NavPathStack new NavPathStack()Builder PageMap(name…

网络安全之漏洞

网络安全中漏洞是什么&#xff1f; 定义 在网络安全领域&#xff0c;漏洞是指系统、应用程序、网络设备等在设计、实现、配置或维护过程中存在的弱点或缺陷。这些弱点能够被攻击者利用&#xff0c;从而突破系统的安全策略&#xff0c;获取未经授权的访问、执行恶意操作或者泄露…

配置ssh-key连接github

GitHub 通过在 2022 年 3 月 15 日删除旧的、不安全的密钥类型来提高安全性。 具体内容参考如下链接 https://docs.github.com/zh/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent mac配置 ssh-keygen -t ed25519 -C …

【Android】解决 ADB 中 SELinux 设置与 `Failed transaction (2147483646)` 错误

解决 ADB 中 SELinux 设置与 Failed transaction (2147483646) 错误 在使用 ADB 进行开发和调试时&#xff0c;经常会遇到由于 Android 系统安全策略&#xff08;SELinux&#xff09;引起的权限问题&#xff0c;尤其是在执行某些操作时&#xff0c;可能会遇到类似 cmd: Failur…

大模型系列4--开源大模型本地部署到微调(WIP)

背景 一直想真正了解大模型对硬件资源的需求&#xff0c;于是准备详细看一篇视频&#xff0c;将核心要点总结记录下。本文内容参考视频&#xff1a;保姆级教程&#xff1a;6小时掌握开源大模型本地部署到微调&#xff0c;感谢up主 训练成本 训练 > 微调 > 推理训练GPT…

仿《公主连结》首页场景的制作(附资源包)

先看效果&#xff08;主要实现点击按钮切换图片&#xff0c;未解锁按钮弹出提示&#xff0c;点击过后播放动画&#xff09; 预备知识&#xff08;单例模式&#xff0c;携程&#xff0c; Resources.Load加载资源的方式&#xff09; 资源准备&#xff08;底部按钮7个图标&#x…

Redis - 集合 Set 及代码实战

Set 类型 定义&#xff1a;类似 Java 中的 HashSet 类&#xff0c;key 是 set 的名字&#xff0c;value 是集合中的值特点 无序元素唯一查找速度快支持交集、并集、补集功能 常见命令 命令功能SADD key member …添加元素SREM key member …删除元素SCARD key获取元素个数SI…

基于Llamaindex的网页内容爬取实战

目的 本文不关注如何解析网页 html 元素和各种 python 爬虫技术&#xff0c;仅作为一种网页数据的预处理手段进行研究。Llamaindex 也并不是爬虫技术的集大成者&#xff0c;使用它是为了后续的存查一体化。 安装依赖 pip install llama-index-readers-web # pip install llam…

《九重紫》逐集分析鉴赏第一集(下)

主标题&#xff1a;《九重紫》一起追剧吧 副标题&#xff1a;《九重紫》逐集分析鉴赏第一集&#xff08;下&#xff09;/《九重紫》逐集分析鉴赏1 接上回分解&#xff0c;窦昭和宋墨都安置城外万佛寺 交谈没一会儿&#xff0c;天还未亮&#xff0c;兵临寺下 记住这个人&…

Introduction to NoSQL Systems

What is NoSQL NoSQL database are no-tabular非數據表格 database that store data differently than relational tables 其數據的存儲方式與關係型表格不同 Database that provide a mechanism機制 for data storage retrieval 檢索 that is modelled in means other than …