luogu P11799 题解

news/2025/2/23 20:49:45/文章来源:https://www.cnblogs.com/rhineofts/p/18732841

来一个不用 trie,但是需要大力分讨的做法。

这个 min 的限制是很难受的:因为如果两个数在某一位上分别是 \(0\)\(1\),那个 \(1\) 仍然可能有贡献。

先考虑一下性质 A: \(a_i\) 全相等的做法。也即求 \(n^2\sum_{j=0}^{m}x\oplus j\)。这个东西就能拆位了,考虑第 \(i\) 位什么时候有贡献,当 \(x\) 的这一位和 \(j\) 的这一位不同时,有 \(2^j\) 的贡献。那么我们实际上把问题转化成了一个计数问题:求 \(0\sim m\) 中钦定第 \(i\) 位为 \(0\)(或是 \(1\))的数的个数。这个东西是很好做的,但是需要一些分讨。可以看代码。

然后我们把 min 转化成 max。方法是先求出 \(\sum_i\sum_j\sum_ka_i\oplus k+a_j\oplus k\)。 这个东西 \(i,j\) 无关,是很好做的。然后这个东西减去 max 就是 min(不转化好像也能做,但是我场上把题看错了,只好这样将错就错。)

重新观察一下式子:要求和的项是两个数异或上同一个数,这个东西有一个很好的性质:若 \(x,y\) 的第 \(i\) 位不同,那么它们异或上同一个数后仍不同。

这个性质是很强的!对于两个不相等的数,我们可以在它们最高的不相同的位处确定大小关系,进而很方便的算贡献:仍然是拆位,然后问题被转化成了上面的计数问题的加强版:限制的位置变成了两个,这个东西仍然可以大力分讨完成,当然也可以数位 DP。

最后,怎么快速进行这个过程呢?用类似基数排序的方法:我们要对一些最高的 \(x\) 位都相同的数按第 \(x\) 位是什么给它们分组。然后组和组间的贡献就可以用上面的方法算。组内贡献只需要递归到最后一层,这时组内所有数都相等,然后用性质 A 的方法去做。

这样这个题就做完了,复杂度为 \(O(n\log V)\)

我的代码可能写的有些冗长,应该有更简单的写法。如果把那几个计数的函数换成数位 DP 应该能短不少。

int calc0(int m, int j) { // 计算 [0, m] 中第 j 位是 0 的数的个数,下同int tot = (1 << j) * (m >> j + 1);if (m & (1 << j)) {tot += 1 << j;} else {tot += (m & ((1 << j) - 1)) + 1;}return tot;
}int calc1(int m, int j) {int tot = (1 << j) * (m >> j + 1);tot += max(0, 1 + (m & ((1 << j + 1) - 1)) - (1 << j));return tot;
}int calc00(int m, int x, int y) { // 第 x 位是 0,第 y 位也是 0int cnt = 0;cnt += (m >> x + 1) * (1 << x - 1);if (m & (1 << x)) {cnt += 1 << (x - 1);} else cnt += calc0(m & ((1 << x) - 1), y);return cnt;
}int calc01(int m, int x, int y) {int cnt = 0;cnt += (m >> x + 1) * (1 << x - 1);if (m & (1 << x)) {cnt += 1 << x - 1;} else {cnt += calc1(m & ((1 << x) - 1), y);}return cnt;
}int calc10(int m, int x, int y) {int cnt = 0;cnt += (m >> x + 1) * (1 << x - 1);if (m & (1 << x)) {int t = m & ((1 << x) - 1);cnt += calc0(t, y);}return cnt;
}int calc11(int m, int x, int y) {int cnt = 0;cnt += (m >> x + 1) * (1 << x - 1);if (m & (1 << x)) {int t = m & ((1 << x) - 1);cnt += calc1(t, y);}return cnt;
}void solve() {int n, m; cin >> n >> m;vi a(n + 1);F (i, 1, n) cin >> a[i];i64 ans = 0;auto solve = [&](auto&& solve, int bit, int l, int r) -> void {if (bit == -1) {int x = a[l], cnt = 1LL * (r - l + 1) * (r - l + 1) % mod;DF (j, w - 1, 0) {if (x & (1 << j)) {ans += 1LL * (1 << j) * calc0(m, j) % mod * cnt % mod;ans %= mod;} else {ans += 1LL * (1 << j) * calc1(m, j) % mod * cnt % mod;ans %= mod;}   }return;}vi h; h.reserve(r - l + 1);int st = 0, ed = r - l;F (i, l, r) {if (!(a[i] & (1 << bit))) {h[ed--] = a[i];}  else h[st++] = a[i];}F (i, l, r) a[i] = h[i - l];// 这里 [l, l + st - 1] 这个区间中的数第 bit 位是 1,其余的数这一位是 0.if ((st and l + st <= r)) { // 这里有一个小剪枝,删了也不影响复杂度。{i64 res = 0;F (i, l, l + st - 1) {DF (j, w - 1, bit + 1) {if (a[i] & (1 << j)) {res += 1LL * (1 << j) * calc00(m, j, bit) % mod;} else {res += 1LL * (1 << j) * calc10(m, j, bit) % mod;}}res += 1LL * (1 << bit) * calc0(m, bit) % mod;DF (j, bit - 1, 0) {if (a[i] & (1 << j)) {res += 1LL * (1 << j) * calc00(m, bit, j) % mod;} else {res += 1LL * (1 << j) * calc01(m, bit, j) % mod;}}res %= mod;}ans += 2 * res * (r - (l + st) + 1) % mod; ans %= mod;}{i64 res = 0;F (i, l + st, r) {DF (j, w - 1, bit + 1) {if (a[i] & (1 << j)) {res += 1LL * (1 << j) * calc01(m, j, bit) % mod;} else {res += 1LL * (1 << j) * calc11(m, j, bit) % mod;}}res += 1LL * (1 << bit) * calc1(m, bit) % mod;DF (j, bit - 1, 0) {if (a[i] & (1 << j)) {res += 1LL * (1 << j) * calc10(m, bit, j) % mod;} else {res += 1LL * (1 << j) * calc11(m, bit, j) % mod;}}res %= mod;}ans += 2 * res * st % mod; ans %= mod;}}if (l <= l + st - 1) solve(solve, bit - 1, l, l + st - 1);if (l + st <= r) solve(solve, bit - 1, l + st, r);}; solve(solve, w - 1, 1, n);//  进行完这个过程,a 是降序的。i64 ALL = 0;F (i, 1, n) { // 这里就是利用 a + b - max(a, b) = min(a, b)int x = a[i]; i64 res = 0;DF (j, w - 1, 0) {if (x & (1 << j)) {res += 1LL * (1 << j) * calc0(m, j);res %= mod;} else {res += 1LL * (1 << j) * calc1(m, j);res %= mod;}   }res = res * 2 * n % mod;ALL = (ALL + res) % mod;}ALL -= ans; ALL %= mod;if (ALL < 0) ALL += mod;cout << ALL << "\n";}

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

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

相关文章

4.优化器 - 模型评估

优化器 - optimizer优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数损失函数(目标函数)值不断逼近全局最小优化器不计算梯度,他只是梯度的更新者,它决定了以什么样的形式更新参数如果损失函数是…

【软件开发】CMake学习笔记

【软件开发】CMake 学习笔记 CMake 是什么? 是构建系统(如 Visual Studio)的文件(如 .vcxproj .sln)的创建器,具体要生成的构建系统可以通过 CMakePresets 文件中的 generator 指定。 构建系统一般不是跨平台的,但 CMake 支持在不同的操作系统上生成不同的构建系统文件,…

Python糖尿病数据分析:深度学习、逻辑回归、K近邻、决策树、随机森林、支持向量机及模型优化训练评估选择

全文链接:https://tecdat.cn/?p=39864 原文出处:拓端数据部落公众号 分析师:Weilong Zhang 本研究旨在利用机器学习和深度学习模型对糖尿病数据进行分析和预测。通过对糖尿病数据集的读取、预处理、特征分析,运用多种机器学习算法如逻辑回归、K近邻、决策树、随机森林、支…

使用MyBatis框架时Mapper传参是否需要使用@Param注解

在使用MyBatis作为Java项目的ORM框架时,在Mapper接口中传递参数需要通过@Param注解指定参数名称,这样才能在Mapper接口对应的xml文件中引用到对应名称的参数。如果不在Mapper接口中明确使用@Param注解时将会报错:找不到指定名称的参数。 追根溯源,这要从MyBatis获取Mapper接…

关于在阿里云服务器上搭建简单的keepalived主备服务器时出现的问题

问题:在进行keepalived主备服务器配置时,仅配置了RID,状态,通讯端口,VRID,优先级,通告报文发送时间,密码认证部分,VIP。在启动服务时,发现两台设备均跳转状态为MASTER。原因:出现这问题的场景是在阿里VPS云服务器网络环境中,因为路由交换层禁用了ARP的广播限制,造…

子串分值

‌输入和初始化‌: 读取字符串 str,并从索引 1 开始存储(C++ 中字符串索引从 0 开始,但这里为了简化计算,从 1 开始)。 n 存储字符串的长度。 数组 l[i] 存储字符 str[i] 上一次出现的位置。 数组 r[i] 存储字符 str[i] 下一次出现的位置。 数组 p 用于临时存储每个字符最…

【专题】2024年新能源汽车市场年度竞争报告汇总PDF洞察(附原数据表)

原文链接: https://tecdat.cn/?p=39740 在当下快速变革的时代,新能源汽车市场正处于关键的发展十字路口。过去几年间,市场经历了一系列深刻的结构性调整,从市场份额的重新分配到消费者行为模式的显著转变,每一个变化都蕴含着巨大的市场信号。深入分析这些变化背后的数据逻…

pikachu靶场搭建教程

详细介绍了pikachu靶场的搭建,并且附有安装包需要的东西phpStudy: 链接: https://pan.baidu.com/s/1fJ-5TNtdDZGUf5FhTm245g 提取码:0278 pikachu-master: Github链接:Github 链接 链接: https://pan.baidu.com/s/1lDdlxNaa3YjhIEj-WWB3qw 提取码:0278打开 phpstudy ,…

2.17周报

一、本周内容总结本周主要进行了蓝桥和天梯的训练,训练了3场蓝桥、2场天梯,剩余时间的就是赛后补题 补题的过程也重新理清了很多知识,包括gcd和lcm的应用,多项式除法的过程等等 对于蓝桥和天梯的赛制,还重新背了下很多算法的板子,包括求最短路的多种方法,不同范围求组合…

来点树链剖分

树链剖分树链剖分学习笔记 引入 给你一棵树,先单点加,再路径求和,你觉得很简单,用树上差分解决了这个问题。 再给你一棵树,先路径加,再单点查询,你觉得很简单,用树上差分解决了这个问题。 又给你一棵树,上述操作都有,而且顺序不分先后,你发现树上差分不能解决这个问…

《轻松上手:LangChain 的安装与验证全流程》

在当今快速发展的技术领域,掌握新工具是提升工作效率的关键。今天,我将为大家详细介绍如何轻松安装 LangChain,并验证其是否成功安装,让你迅速开启探索这一强大工具的旅程。 首先,在命令行中运行以下命令来安装 LangChain: pip install langchain安装完成后,为了确保一切…

双向广搜 P1032 洛谷 [NOIP 2002 提高组] 字串变换

双向广搜 P1032 洛谷 [NOIP 2002 提高组] 字串变换 题目背景 本题不保证存在靠谱的多项式复杂度的做法。测试数据非常的水,各种做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。 本题为搜索题,本题不接受 hack 数据。关于此类题目的详细内容 题目描述 已知有两…