【ACM算法竞赛日常训练】【奇♂妙拆分】【区区区间间间】【小AA的数列】数学 | 位运算 | 前缀和

DAY16共3题:

  • 奇♂妙拆分(简单数学)

  • 区区区间间间(单调栈)

  • 小AA的数列(位运算dp)

🎈 作者:Eriktse
🎈 简介:19岁,211计算机在读,现役ACM银牌选手🏆力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)🚀
🎈 阅读原文获得更好阅读体验:【ACM算法竞赛日常训练】DAY16【奇♂妙拆分】【区区区间间间】【小AA的数列】数学 | 位运算 | 前缀和

奇♂妙拆分(简单数学)

根据贪心的想法,若要使得因子尽可能多,那么因子应当尽可能小,大于根号n的因子至多一个,从小到大枚举[1, sqrt(n)]的所有整数,如果i能够整除n就作为一个因子。

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;void solve()
{int n;cin >> n;set<int> st;for(int i = 1;i <= n / i; ++ i)if(n % i == 0)st.insert(i), n /= i;st.insert(n);cout << st.size() << '\n';
}signed main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _;cin >> _;while(_ --)solve();return 0;
}

区区区间间间(单调栈)

题意:给定一个数组,求所有子区间的最大值与最小值的差的和。

如果暴力枚举肯定不行,单单是子区间个数就有n ^ 2个,所以我们应该考虑每一个元素对答案的贡献,也就是说我们需要知道某个元素a[i]它会在多少个区间里作为最大值,在多少个区间里作为最小值

我们预处理出四个数组,分别是lmax[], rmax[], lmin[], rmin[]表示点i作为最大值的左右最远位置,和作为最小值的左右最远位置(lmax[i] = j,表示在区间[j, i]中的最大值都是a[i],其他的三个数组类似定义)。

用单调栈可以处理出这四个数组,一下以求lmax[]举例,维护一个单调不增栈,栈内存放的是下标

初始时栈内仅有一个a[0] = inf

当我们遇到一个a[i]时,不断地判断栈顶元素,如果栈顶元素比a[i]小,说明这个栈顶应当弹出。

当更新完毕后,此时的栈顶的右边相邻位置就是a[i]往左的最远的位置了,因为此时栈顶是a[i]往左的第一个大于等于a[i]的位置,那么这中间的元素都会小于a[i]

其他的三个数组类似,注意,如果我们处理lmax用的是单调不增栈,那么处理rmax就应当用单调递增栈,而不是单调不减栈,否则可能出现区间重复表示或没有归属的问题(自己思考)。

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 9, inf =8e18;
int a[N], stk[N], top, lmax[N], rmax[N], lmin[N], rmin[N];void solve()
{int n;cin >> n;for(int i = 1;i <= n; ++ i)cin >> a[i];a[0] = a[n + 1] = inf;top = 0;stk[++ top] = 0;for(int i = 1;i <= n; ++ i){while(top && a[i] > a[stk[top]])top --;lmax[i] = stk[top] + 1;stk[++ top] = i;}top = 0;stk[++ top] = n + 1;for(int i = n;i >= 1; -- i){while(top && a[i] >= a[stk[top]])top --;rmax[i] = stk[top] - 1;stk[++ top] = i;}a[0] = a[n + 1] = -inf;top = 0;stk[++ top] = 0;for(int i = 1;i <= n; ++ i){while(top && a[i] < a[stk[top]])top --;lmin[i] = stk[top] + 1;stk[++ top] = i;}top = 0;stk[++ top] = n + 1;for(int i = n;i >= 1; -- i){while(top && a[i] <= a[stk[top]])top --;rmin[i] = stk[top] - 1;stk[++ top] = i;}int ans = 0;for(int i = 1;i <= n; ++ i){ans += a[i] * (rmax[i] - i + 1) * (i - lmax[i] + 1);ans -= a[i] * (rmin[i] - i + 1) * (i - lmin[i] + 1);}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _;cin >> _;while(_ --)solve();return 0;
}

小AA的数列(位运算 | 前缀和)

这道题一看有点懵,感觉不是很好处理,但依然是套路题。

看到异或,我们应该想把每一个二进制位拆分开,实际上这里约32位二进制位可以先认为是相互独立的,对于每一位都计算出贡献,然后按照位权重加和即可。

异或题的套路基本都是拆分二进制,整体考虑起来比较复杂,拆分后会简单很多。

先不管L, R

假如我们考虑数组1 2 3 4 5的第0位:

获取第0位后得到b数组:1 0 1 0 1

因为我们要得到区间内1的个数,所以处理一个异或前缀和p[]是自然而然的,然后我们枚举每一位作为左端点,看看会得到一个怎样的式子:

sum=∑j=i+1j+=2,j≤np[j]⊕p[i−1]

我们知道异或其实就是% 2的加法,也是% 2减法,所以我们将异或前缀和改为普通前缀和p[],以上的柿子可以转化为:

sum=∑j=i+1j+=2,j≤n[(p[j]−p[i−1])(mod2)]

那么我们就可以对p再做一个前缀和p2,但是p2的步长应为2。

然后上面的柿子就等价于(其中l, rj的上下限,需要保证与i - 1奇偶性相同,j的个数为(r - l + 2) / 2):

sum=|p2[r]−p2[l−1]−p[i−1]∗((r−l+2)/2))|

因为这个p2存在p2[-1]的情况,所以我们做个小小的便宜,方便代码的编写(其实你想要特判也行,只是不太方便,也容易出错)。

注意一下其他细节即可。 

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 109, p = 1e9 + 7, T = 100;
int a[N], b[N], p1[N], p2[N];signed main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n, l, r;cin >> n >> l >> r;for(int i = 1;i <= n; ++ i)cin >> a[i];int ans = 0;for(int w = 0;w <= 32; ++ w){for(int i = 1;i <= n; ++ i)b[i] = a[i] >> w & 1;for(int i = 1;i <= n; ++ i)p1[T + i] = (b[i] + p1[T + i - 1]) % 2;for(int i = 1;i <= n; ++ i)p2[T + i] = p1[T + i] + p2[T + i - 2];int sum = 0;for(int i = 1;i <= n; ++ i){int j1 = max(i + 1, l + i - 1), j2 = min(n, r + i - 1);if((j1 - i) % 2 == 0)j1 ++;if((j2 - i) % 2 == 0)j2 --;if(j2 < j1)continue;sum += abs(p2[T + j2] - p2[T + j1 - 2] - p1[T + i - 1] * ((j2 - j1) / 2 + 1));}ans = (ans + (1ll << w) * sum % p) % p;}cout << ans << '\n';return 0;
}

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

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

相关文章

应用案例|基于三维机器视觉的机器人纸箱拆码垛应用解决方案

Part.1 项目背景 在现代物流和制造行业中&#xff0c;纸箱的拆码垛操作是一项重要且频繁的任务。传统的纸箱拆码垛工作通常由人工完成&#xff0c;这种方式存在劳动强度大、生产效率低以及人为操作容易导致错误等问题&#xff0c;严重影响物料的安全运输和质量。为了满足物流行…

【Antd】antd form表单的rules文案无法跟随状态重渲染的原因及解决办法

问题背景 我有两个表单项&#xff0c;当我选择出库类型&#xff0c;调用onChange改变inOutType 状态&#xff0c;这时候发现这句代码不生效&#xff1a; rules{[{ required: true, message: 请选择${inOutType 1 ? 持有人 : 负责人} }]}示例代码 <TypographyForm.Group…

大模型“瘦身”进手机 下一个iPhone时刻将至?

一股“端侧大模型”浪潮正在涌来。华为、高通等芯片巨头正探索将AI大模型植入端侧&#xff0c;让手机实现新一代物种进化。 相比ChatGPT、Midjourney等AI应用依赖云端服务器提供服务&#xff0c;端侧大模型主打在本地实现智能化。它的优势在于能够更好地保护隐私&#xff0c;同…

有没有推荐的golang的练手项目?

前言 下面是github上的golang项目&#xff0c;适合练手&#xff0c;可以自己选择一些项目去练习&#xff0c;整理不易&#xff0c;希望能多多点赞收藏一下&#xff01;废话少说&#xff0c;我们直接进入正题>>> 先推荐几个教程性质的项目&#xff08;用于新手学习、巩…

Python中replace()函数详解

目录 语法 参数 返回值 实例 语法 replace() 函数是 Python 字符串对象的内置方法之一&#xff0c;用于将字符串中的指定子串替换为新的子串。 str.replace(old, new[, count])参数 old&#xff1a;需要被替换的旧子串。new&#xff1a;替换后的新子串。count&#xff…

RS-232标准

目录 1、概述2、RS-232接口的特点3、RS-232接口协议【仿真】 1、概述 RS-232接口是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。它的全名是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换…

redis学习笔记(五)

文章目录 hash&#xff08;哈希&#xff09;&#xff08;1&#xff09;设置指定键的属性/域&#xff08;2&#xff09;获取指定键的域/属性的值&#xff08;3&#xff09;获取hash的所有域值对&#xff08;4&#xff09;删除指定键的域/属性&#xff08;5&#xff09;判断指定属…

Hadoop理论及实践-HDFS读写数据流程(参考Hadoop官网)

NameNode与DataNode回顾 主节点和副本节点通常指的是Hadoop分布式文件系统&#xff08;HDFS&#xff09;中的NameNode和DataNode。 NameNode&#xff08;主节点&#xff09;&#xff1a;NameNode是Hadoop集群中的一个核心组件&#xff0c;它负责管理文件系统的命名空间和元数据…

arcgis pro 3.0.2 安装及 geemap

arcgis pro 3.0.2 安装及 geemap arcgis pro 3.0.2 安装 arcgis pro 3 版本已经很多了&#xff0c;在网上找到资源就可以进行安装 需要注意的是&#xff1a;有的文件破解文件缺少&#xff0c;导致破解不成功。 能够新建地图就是成功了&#xff01; geemap安装 1.需要进行环…

Python web实战之Django 的 WebSocket 支持详解

关键词&#xff1a;Python, Django, WebSocket, Web 如何使用 Django 实现 WebSocket 功能&#xff1f;本文将详细介绍 WebSocket 的概念、Django 的 WebSocket 支持以及如何利用它来创建动态、响应式的 Web 应用。 1. WebSocket 简介 1.1 什么是 WebSocket&#xff1f; 在 W…

【果树农药喷洒机器人】Part7:静态PWM变量喷药实验

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

k8s界面化平台dashboard、kubesphere、Rancher对比

k8s集群管理dashboard有很多&#xff0c;比如kuboard、官方发dashboard、kubesphere、Rancher等等。 Dashboard、KubeSphere 和 Rancher 都是流行的 Kubernetes 管理和操作界面。它们都提供了图形化的用户界面&#xff0c;以简化对 Kubernetes 集群的管理和监控。每个工具都有其…

【编程指南】ES2016到ES2023新特性解析一网打尽

ES2016 Array.prototype.includes() Array.prototype.includes 方法&#xff1a; 这个方法用于检查数组是否包含特定元素&#xff0c;如果包含则返回 true&#xff0c;否则返回 false // 我有一个水果篮子 const fruitBasket [apple, banana, orange, grape];// 我要检查篮…

pycharm配置conda虚拟环境

&#x1f4d5;作者简介&#xff1a;热编程的贝贝&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步健身&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于贝贝的日常汇报系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏深度学习、…

iOS开发-实现二维码扫一扫Scan及识别图片中二维码功能

iOS开发-实现二维码扫一扫Scan及识别图片中二维码功能 在iOS开发中&#xff0c;会遇到扫一扫功能&#xff0c;扫一扫是使用摄像头扫码二维码或者条形码&#xff0c;获取对应二维码或条形码内容字符串。通过获得的字符串进行跳转或者打开某个页面开启下一步的业务逻辑。 https…

RFID工业识别技术:供应链智能化的科技颠覆

RFID工业识别技术&#xff0c;作为物联网的先锋&#xff0c;正在供应链管理领域展现着前所未有的科技颠覆。从物料追踪到库存管理&#xff0c;再到物流配送&#xff0c;RFID技术以其高效的数据采集和智能的自动化处理&#xff0c;彻底改变着传统供应链的运营方式。 RFID在物料追…

ETF套利及交易者如何进行套利的

ETF套利 什么是ETF套利为什么同一ETF在不同交易所上的价格会出现差异&#xff1f;如何操作ETF套利交易所如何解决ETF套利问题的&#xff1f; 什么是ETF套利 ETF&#xff08;Exchange-Traded Fund&#xff09;套利是一种通过利用市场中不同交易所交易价格之间的差异来获得利润的…

Django各种缓存的配置

Django提供了多种缓存后端&#xff0c;如内存缓存、文件缓存、数据库缓存、Memcached和Redis等。根据项目需求选择合适的缓存后端。 settings配置 在Django项目的settings.py文件中&#xff0c;找到或新增CACHES配置项。根据所选的缓存后端&#xff0c;配置相应的参数。以下是…

LeetCode 2811. Check if it is Possible to Split Array【脑筋急转弯;前缀和+动态规划或记忆化DFS】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Three.js之相机、渲染器、光源、动画、性能监测

参考资料 第一个3D案例—透视投影相机第一个3D案例—渲染器…Canvas画布布局和全屏 知识点 透视投影相机PerspectiveCameraWebGL渲染器WebGLRenderer辅助观察坐标系AxesHelper漫反射网格材质MeshLambertMaterial点光源PointLight点光源辅助观察PointLightHelper环境光Ambien…