当前位置: 首页 > article >正文

【CF】Day62——Codeforces Round 948 (Div. 2) CD (思维 + LCM + 枚举因数 | 思维 + 哈希)

C. Nikita and LCM

题目:

思路:

非常好的思维题,顺便复习了一下快速枚举因数和lcm的性质

我们先来看答案的上界,即全选,此时说明 lcm(a1,a2,a3,...) > a_max 其中 a_max 为 a 中最大的数,那么如果答案不是 n 呢?

既然不是 n,也就是说如果我们全选的话这个数会出现在 a 中,而如果要出现在 a 中,显然这个数一定是 a_max

那么我们可以假设最后不在 a 中的 lcm 为 m,而根据 lcm 性质我们可以知道 子序列的lcm 肯定是整个序列lcm 的一个 因数 x,所以我们可以枚举 a_max 的因数,如果对于 a[i] 有 x % a[i] == 0,说明我们可以选 a[i], 然后快速枚举以及遍历一遍累加答案,最后取最大值即可,由于 n 是 2000,所以时间复杂度是可以接受的

特别注意,由于因子可能存在原数组,所以我们还要用 map 存储一下出现过的数字

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"int gcd(int a,int b)
{return !b ? a : gcd(b, a % b);
}int lcm(int a,int b)
{return a * b / gcd(a,b);
}void solve()
{int n;cin >> n;vector<int> a(n);map<int, int> mp;int LCM = 1,mx=0;for (int i = 0; i < n; i++){cin >> a[i];mp[a[i]]++;mx = max(mx, a[i]);}for (int i = 0; i < n; i++){LCM = lcm(LCM, a[i]);if (LCM > mx){cout << n << endl;return;}}vector<pair<int, int>> b;for (auto& x : mp)b.push_back(x);auto fuc = [&](int x) ->int{int Lcm = 0, cnt = 0;for (auto& son : b){if (x % son.first == 0){cnt += son.second;if (Lcm == 0)Lcm = son.first;elseLcm = lcm(Lcm, son.first);}}if (Lcm != x)cnt = 0;return cnt;};int res = 0;for (int i = 1; i*i <= mx; i++){if (mx % i == 0){if (!mp[i])res = max(res, fuc(i));if (!mp[mx/i])res = max(res, fuc(mx/i));}}cout << res << endl;
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}

D. XORificator

题目:

 

 

思路:

无敌哈希运用,学到了新的想法,值得反复观看

题目告诉我们可以使用操作使得每一行的 0/1 翻转,然后问我们在所有的操作可能中最后最多有多少个特殊列,其中特殊列为该列中只有一个 1

我们首先发现,好像除了暴力枚举没啥法子能做了?事实上确实是这样,所以我们得想想怎么优化比较好

我们发现,如果我们钦定某个 (i,j) 为 1,那么全局情况就唯一了,那我们可以枚举每一个点,如果要让他变成这一列唯一的 1 我们要怎么操作,然后把操作存储下来,而这个操作每一次只有变换或者不变换,即可以看作一个 01 串,那我们就可以使用字符串哈希的类似方法来处理

具体的,我们先获取如果要让这一列全变成 0 要执行什么操作,然后枚举每一位让他取反,这样我们就知道如果要只让他为 1 的操作是什么呢,那么如何储存哈希值呢?我们为了防止哈希冲突,我们可以使用双哈希,我们定义执行操作为取这一点的哈希,这样我们就能获得对应的两个哈希了,然后我们用一个 map 存储对应操作的答案,这样后续遇到相同的哈希值(即相同的操作时)我们就知道谁的答案最大了,同时我们还要储存此时是让哪个 (i,j) 为 1,这样便于我们输出答案

具体实现看代码,还是有点细节的,注意哈希值这里是随机数,这样不容易被数据仙人卡

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
#include <random>
#include <ctime>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"
mt19937_64 rnd(time(0));
void solve()
{int n, m;cin >> n >> m;vector<string> ma(n);for (int i = 0; i < n; i++){cin >> ma[i];}vector<int> hash1(n), hash2(n);for (int i = 0; i < n; i++){hash1[i] = rnd(), hash2[i] = rnd();}map<pair<int, int>, int> hash;int res = 0;pair<int, int> point = { 0,0 };for (int j = 0; j < m; j++){int h1 = 0, h2 = 0;//计算将这一列全变成 0 的操作的哈希值for (int i = 0; i < n; i++){if (ma[i][j] == '1')h1 ^= hash1[i], h2 ^= hash2[i];}for (int i = 0; i < n; i++){//如果第 i 行的为 1 的操作的哈希值h1 ^= hash1[i], h2 ^= hash2[i];hash[{h1, h2}]++;if (res < hash[{h1, h2}]){res = hash[{h1, h2}];point = { i,j };}//变回全是 0 的哈希值h1 ^= hash1[i], h2 ^= hash2[i];}}cout << res << endl;for (int i = 0; i < n; i++){if (ma[i][point.second] == '1')cout << (i != point.first);elsecout << (i == point.first);}cout << endl;
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}

http://www.lryc.cn/news/2379921.html

相关文章:

  • 基于requests_html的python爬虫
  • 循环神经网络:捕捉序列数据中的时间信息
  • 第35周Zookkeeper+Dubbo 面试题精讲
  • 聊聊更新中断和更新事件那些事儿
  • STM32:按键模块 传感器模块 以及 相关C语言知识(详细讲解)
  • C++23 std::mdspan:多维数组处理新利器
  • 基于高德MCP2.0的智能旅游攻略系统设计与实现
  • 【时时三省】(C语言基础)用函数实现模块化程序设计
  • Flink流处理:实时计算URL访问量TopN(基于时间窗口)
  • 初识函数------了解函数的定义、函数的参数、函数的返回值、说明文档的书写、函数的嵌套使用、变量的作用域(全局变量与局部变量)
  • java collection集合特点知识点详解
  • ngx_http_realip_module 模块概述
  • 自定义CString类与MFC CString类接口对比
  • 华为OD机试真题——考勤信息(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • Go语言测试用例的执行与分析
  • vue3 vite 路由
  • MyBatis:动态SQL
  • 游戏引擎学习第280天:精简化的流式实体sim
  • femap许可与多用户共享
  • 王树森推荐系统公开课 排序03:预估分数融合
  • 网络I/O学习-poll(三)
  • k8s(12) — 版本控制和滚动更新(金丝雀部署理念)
  • 【git config --global alias | Git分支操作效率提升实践指南】
  • chrome源码中WeakPtr 跨线程使用详解:原理、风险与最佳实践
  • 【Go】从0开始学习Go
  • Windows 安装显卡驱动
  • 模块与包的导入
  • Google设置app-ads.txt
  • docker安装rockerMQ
  • 交叉引用、多个参考文献插入、跨文献插入word/wps中之【插入[1-3]、连续文献】