2-2基础算法-Nim和/前缀和/差分

文章目录

  • 一.Nim和
  • 二.前缀和&区间和
  • 三.差分

一.Nim和

Nim游戏是一个数学策略游戏,通常涉及两名玩家轮流从几堆物品(如石子或饼干)中取走一定数量的物品。每个玩家每次可以从任意一堆中取走任意数量的物品,但必须至少取走一个。最后无法进行操作的玩家输掉游戏。

Nim和是所有堆中物品数量的二进制异或(XOR)结果。在计算Nim和时,我们将每堆物品的数量转换为二进制数,然后对这些二进制数进行异或运算。例如,如果有三堆物品,数量分别是3、5、7,则它们的二进制表示分别是011、101、111。它们的Nim和是011 XOR 101 XOR 111 = 001。

在标准的Nim游戏中,如果Nim和为0,那么当前的局面对于后手(即非当前回合的玩家)是有利的,因为后手可以通过策略性地取物品,始终保持Nim和为0的状态,直到游戏结束。如果Nim和非0,先手(当前回合的玩家)处于优势,因为他们可以通过一次操作改变堆的状态,使Nim和变为0,从而控制游戏进程。

[例] Alice和Bob的爱恨情仇

在这里插入图片描述
在这里插入图片描述

评测系统

分析:此题游戏规则中有额外的限制(每次只能取走k的奇数倍的物品),我们需要对标准Nim游戏的策略进行调整。我们可以通过检查每堆中物品的数量是否可以通过取走k的奇数倍来减少到Nim和的值,从而确定哪位玩家拥有获胜策略。

#include <iostream>
#include <vector>
using namespace std;
int power(int base, int exp) {int result=1;while (exp) {result = result * base;exp--;}return base;
}
bool canwin(int a[], int n, int k) {int nimsum = 0;for (int i = 0; i < n; i++) {nimsum = nimsum ^ a[i];//异或^}if (nimsum == 0)return false;for (int i = 0; i < n; i++) {int num = a[i];//第i堆饼干数量for (int j = 1; power(j,k) <= num; j+=2) { //保证j是奇数if (num - power(j, k) == (nimsum ^ num)) //即:如果if条件满足,那么当前玩家可以通过这次移动使得整个游戏的Nim和变为0return true;}}return false;
}
int main()
{int n, k;cin >> n >> k;int a[2000005];for (int i = 0; i < n; i++) {cin >> a[i];}bool wins = canwin(a, n, k);cout<<(wins ? "Alice" : "Bob");
}

二.前缀和&区间和

1.前缀和原理和特点
定义:(类似于前n项和)
prefix[0]=0
在这里插入图片描述
性质:
在这里插入图片描述
前缀和可以在O(1)的复杂度处理一段区间的和
如:数组l到r的和,等于p[r]-p[l-1]
在这里插入图片描述
2.例题
(1)区间次方和

在这里插入图片描述
在这里插入图片描述

评测系统

常规方式可能超时

由于k比较小,我们可以定义5个数组,分别表示原数组的1~5次幂,然后只需输出l ~ r之间元素的和即可。整个过程可以借助二维数组实现。此方法仍然会超时

再加上前缀和

#include <iostream>
#include <vector>
using namespace std;
const int value= 1e9+7;
int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n, m;cin >> n >> m;long long arr[6][100005];for (int i = 1; i <= n; i++) { //输入与k次方cin >> arr[1][i];for (int k = 2; k <= 5; k++) {arr[k][i] = arr[k - 1][i] * arr[1][i]%value;}}long long prefix[6][100005];//前缀和数组for (int i = 1; i <= 5; i++) {for (int j = 1; j <= n; j++) {prefix[i][j] = (prefix[i][j - 1] + arr[i][j]) % value;}}while (m--) {int a, b, c;cin >> a >> b >> c;//在计算过程中对每个元素都取模,会导致后面元素不一定大于前面元素//最终结果仍要取模,并考虑负数的出现cout << (prefix[c][b]-prefix[c][a-1]+value)%value << endl;}
}

(2)大石头的搬运工
在这里插入图片描述
在这里插入图片描述
评测系统

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int main()
{int n;cin >> n;pair<int, int> q[N];//初始数据for (int i = 1; i <= n; ++i) {cin >> q[i].second >> q[i].first;//first初始位置,second权重}sort(q+1, q + n+1);long long s = 0;long long prefix[N] = { 0 }; //从第一个位置到位置i的所有石头 移动到位置i的总费用for (int i = 1; i <= n; ++i) {prefix[i] =prefix[i - 1] + s * (q[i].first - q[i - 1].first);s += q[i].second;}s = 0;long long nextfix[N] = { 0 };//从位置i到最后一个位置的所有石头 移动到位置i的总费用for (int i = n; i >= 1; --i) {nextfix[i] =nextfix[i + 1]+ s * (q[i + 1].first - q[i].first);s += q[i].second;}long long res=1e18;for (int i = 1; i <= n; ++i) {res = min(res, prefix[i] + nextfix[i]);}cout << res;
}

(3)最大数组和
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
评测系统

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5+5;
int main()
{int t;cin >> t;long long sum;while (t--) {long long a[N] = { 0 };int n, k;cin >> n >> k;sum = 0;for (int i = 1; i <= n; ++i) {cin >> a[i];sum += a[i];}sort(a+1, a + n+1);long long pre[N] = { 0 }, nex[N] = { 0 };for (int i = 1; i <= n; ++i) {//前缀和pre[i] = pre[i - 1] + a[i];}for (int i = n; i >= 1; --i) {//后缀和nex[i] = nex[i + 1] + a[i];}long long temp = 1e18;for (int i = 0; i <= k; ++i) {int cntmin = i * 2;//对前面处理i次,删掉了开头的2i个数int cntmax = k - i;//对后面操作了k-i次,删掉了尾部的k-i个数temp=min(temp,pre[cntmin] + nex[n-cntmax+1]);}cout << sum - temp << endl;}
}

三.差分

差分的主要优势是可以快速地对原数组的一个区间内的所有元素进行同样的增加或减少操作。

1.原理
定义:差分定义为原数组相邻元素之间的差值
a[]原数组,diff差分数组
其中diff[0]=a[0]
在这里插入图片描述
性质:差分数组的前缀和等于原数组
在这里插入图片描述

如果我们想对区间[k,r]中的元素都加x
只需:
从k到数组末尾的元素都加x:diff[k]+=x
r+1及其以后的元素都减x:diff[r+1]-=x

这里diff[k]+=x的意义是,a[k]比a[k-1]多了x。a[k+1]和a[k]的差值要想保持不变,也a[k+1]也需要加x,以此类推

注:只有使用前缀和输出才是有效更新

2.练习
(1)区间更新
在这里插入图片描述
评测系统

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int main()
{int n, m;while (cin >> n >> m) {int a[N] = { 0 }, diff[N] = { 0 }, prefix[N] = { 0 };for (int i = 1; i <= n; i++) {cin >> a[i];}for (int i = 1; i <= n; i++) {diff[i] = a[i] - a[i - 1];}while (m--) {int x, y, z;cin >> x >> y >> z;diff[x] += z;diff[y+1] -= z;}for (int i = 1; i <= n; i++) { //使用前缀和还原prefix[i] = prefix[i - 1] + diff[i];}for (int i = 1; i <= n; i++) {cout << prefix[i] << " ";}cout << endl;}
}

(2)小明的彩灯
在这里插入图片描述
在这里插入图片描述

评测系统

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 5e5 + 5;  //修改
int main()
{int n, q;cin >> n >> q;long long a[N] = { 0 }, diff[N] = { 0 }, prefix[N] = { 0 };  //修改for (int i = 1; i <= n; i++) {cin >> a[i];}for (int i = 1; i <= n; i++) {diff[i] = a[i] - a[i - 1];}while (q--) {int x, y, z;cin >> x >> y >> z;diff[x] += z;diff[y + 1] -= z;}for (int i = 1; i <= n; i++) {prefix[i] = prefix[i - 1] + diff[i];}for (int i = 1; i <= n; i++) {  //修改if (prefix[i] > 0)cout << prefix[i] << " ";elsecout << 0 <<" ";}cout << endl;
}

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

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

相关文章

使用qt实现四则运算计算机项目

这是我们要包含的头文件 #include <QWidget> #include<QStack> #include<string.h> #include<string> 这是我在ui界面创建的计算机基础框架。 接下来要实现按住每个按钮在白框内显示&#xff1b; 因此我们要定义一个QString 类型的变量 QString e…

Linux系统上64位ATT汇编语言多个源文件计算两个数的平方

运行程序的环境 sudo lsb_release -a看到操作系统是Ubuntu 22.04 LTS。 sudo uname -r看到内核版本是5.15.0-86-generic。 sudo as --version看到as的版本是2.38。 sudo ld --version看到ld的版本是2.38。 sudo gcc --version看到gcc版本是11.2.0。 sudo gdb --version看到gdb…

Yum仓库架构解析与搭建实践

1.Yum仓库搭建 1.1本地Yum仓库图解 1.2Linux本地仓库搭建 配置本地光盘镜像仓库 1&#xff09;挂载 [roothadoop101 ~]# mount -t iso996 /dev/cdrom/mnt 2&#xff09;查看 [rooothadoop101 ~] # df -h | |grep -i mnt /dev/sr0 4.6G 4.4G 3&#xf…

服务器上配置jupyter,提示Invalid credentials如何解决

我是按照网上教程在服务器上安装的jupyter以及进行的密码配置&#xff0c;我利用 passwd()这个口令生成的转译密码是"argon...."。按照教程配置jupyter notebook配置文件里面的内容&#xff0c;登陆网页提示"Invalid credentials"。我谷歌得到的解答是&…

学生选课系统基础版

目录 一.Java 中的集合框架&#xff08;上&#xff09; 1.Java中的集合框架概述 2.Collection接口&接口简介 3.学生选课——创建学生类和课程类 4.学生选课——添加课程Ⅰ 5.学生选课——添加课程Ⅱ 6.学生选课——课程查询 7.学生选课——课程修改 8.学生选课——课程删…

EduSoho教培系统 任意文件读取漏洞复现(CNVD-2023-03903)

0x01 产品简介 EduSoho教培系统是由杭州阔知网络科技有限公司研发的开源网校系统 0x02 漏洞概述 该教培系统classroom-course-statistics接口存在未授权任意文件读取漏洞,通过该漏洞攻击者可以读取到config/parameters.yml文件的内容,拿到该文件中保存的secret值以及数据库…

ShenYu网关Http服务探活解析

文章目录 网关端服务探活admin端服务探活 Shenyu HTTP服务探活是一种用于检测HTTP服务是否正常运行的机制。它通过建立Socket连接来判断服务是否可用。当服务不可用时&#xff0c;将服务从可用列表中移除。 网关端服务探活 以divide插件为例&#xff0c;看下divide插件是如何获…

Java监听器与观察者模式

Java监听器与观察者模式 Java中的监听器&#xff08;Listener&#xff09;和观察者模式&#xff08;Observer Pattern&#xff09;都是用于处理对象间的事件通知和响应的设计模式。它们的目的是在对象之间建立一种松散的耦合&#xff0c;使得一个对象的状态变化可以通知到其他…

vue中element-ui日期选择组件el-date-picker 清空所选时间,会将model绑定的值设置为null 问题 及 限制起止日期范围

一、问题 在Vue中使用Element UI的日期选择组件 <el-date-picker>&#xff0c;当你清空所选时间时&#xff0c;组件会将绑定的 v-model 值设置为 null。这是日期选择器的预设行为&#xff0c;它将清空所选日期后将其视为 null。但有时后端不允许日期传空。 因此&#xff…

Kubernetes 容器编排(1)

前言 知识扩展 早在 2015 年 5 月&#xff0c;Kubernetes 在 Google 上的搜索热度就已经超过了 Mesos 和 Docker Swarm&#xff0c;从那儿之后更是一路飙升&#xff0c;将对手甩开了十几条街,容器编排引擎领域的三足鼎立时代结束。 目前&#xff0c;AWS、Azure、Google、阿里云…

使用 PyTorch FSDP 微调 Llama 2 70B

引言 通过本文&#xff0c;你将了解如何使用 PyTorch FSDP 及相关最佳实践微调 Llama 2 70B。在此过程中&#xff0c;我们主要会用到 Hugging Face Transformers、Accelerate 和 TRL 库。我们还将展示如何在 SLURM 中使用 Accelerate。 完全分片数据并行 (Fully Sharded Data P…

深入学习 C++编程,数据结构与算法关系

数据结构是计算机科学中非常重要的概念之一。它是一种组织和存储数据的方式&#xff0c;能够有效地操作和管理数据&#xff0c;以便提高算法的效率。 以下是一些为什么要有数据结构的原因&#xff1a; (1) 数据组织&#xff1a;数据结构可以帮助我们组织和管理大量的数据。通过…

【elementui笔记:el-table表格的输入校验】

之前做得比较多的校验是在el-form表单里做的&#xff0c;但有时也遇到&#xff0c;需要在table内输入数据&#xff0c;然后校验输入的数据是否符合要求的情况。因此记录一下。 思路&#xff1a; 1.需要借助el-form的校验&#xff0c;el-table外层嵌套一层el-form&#xff0c;使…

世界5G大会

会议名称:世界 5G 大会 时间:2023 年 12 月 5 日-12 月 8 日 地点:河南郑州 一、会议简介 世界 5G 大会,是由国务院批准,国家发展改革委、科技部、工 信部与地方政府共同主办,未来移动通信论坛联合属地主管厅局联合 承办,邀请全球友好伙伴共同打造的全球首个 5G 领域…

CleanMyMac X2024值不值得下载?

macOS已经成为最受欢迎的桌面操作系统之一&#xff0c;它提供了直观、简洁的用户界面&#xff0c;使用户可以轻松使用和管理系统。macOS拥有丰富的应用程序生态系统&#xff1b;还可以与其他苹果产品和服务紧密协作&#xff0c;如iPhone、iPad&#xff0c;用户可以通过iCloud同…

# 和 $ 的区别②

上节博客说了使用 # 的时候,如果参数为 String ,会自动加上单引号 但是当参数为String 类型的时候,也有不需要加单引号的情况,这时候用 # 那就会出问题 比如根据 升序(asc) 或者 降序(desc) 查找的时候,加了单引号那就会报错 这个时候我们就只能使用 $ 如果看不懂代码,就去…

jmeter,同一线程组内,调用cookie实现接口关联

取cookie方式参考上一篇&#xff1a;jemeter&#xff0c;取“临时重定向的登录接口”响应头中的cookie-CSDN博客 元件结构 登录后要执行的接口为“api/get_event_list/”&#xff0c;在该HTTP请求下创建HTTP信息头管理器&#xff0c;配置如下&#xff1a; 执行测试后&#xff0…

Docker网络模式:深度理解与容器网络配置

Docker 的网络模式是容器化应用中一个关键而复杂的方面。本文将深入讨论 Docker 的网络模式&#xff0c;包括基本概念、常用网络模式以及高级网络配置&#xff0c;并通过更为丰富和实际的示例代码&#xff0c;帮助读者全面掌握如何理解和配置容器网络。 Docker网络基础 1 Doc…

Android--Jetpack--Navigation详解

须知少日拏云志&#xff0c;曾许人间第一流 一&#xff0c;定义 Navigation 翻译成中文就是导航的意思。它是谷歌推出的Jetpack的一员&#xff0c;其目的主要就是来管理页面的切换和导航。 Activity 嵌套多个 Fragment 的 UI 架构模式已经非常普遍&#xff0c;但是对 Fragmen…

Sql标准梳理

SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系型数据库管理系统&#xff08;RDBMS&#xff09;的标准化语言。SQL标准由国际标准化组织&#xff08;ISO&#xff09;和美国国家标准化组织&#xff08;ANSI&#xff09;制定和维护&#xff0c;旨在提供…