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

力扣 第 463 场周赛

1. 按策略买卖股票的最佳时机

给你两个整数数组 prices 和 strategy,其中:

prices[i] 表示第 i 天某股票的价格。
strategy[i] 表示第 i 天的交易策略,其中:
-1 表示买入一单位股票。
0 表示持有股票。
1 表示卖出一单位股票。
同时给你一个 偶数 整数 k,你可以对 strategy 进行 最多一次 修改。一次修改包括:

选择 strategy 中恰好 k 个 连续 元素。
将前 k / 2 个元素设为 0(持有)。
将后 k / 2 个元素设为 1(卖出)。
利润 定义为所有天数中 strategy[i] * prices[i] 的 总和 。

返回你可以获得的 最大 可能利润。

注意: 没有预算或股票持有数量的限制,因此所有买入和卖出操作均可行,无需考虑过去的操作。

解题思路:容易想到滑窗的思路, 通过计算增量, 结果就是原来的乘积+增量, 先计算第一个窗口, 对于数组strategy, 前k/2个数变成0, 增量为-strategy[I]*prices[i],  后k/2变成1, 增量为prices[i]*1-strategy[I]*prices[i], 向右滑动的过程中, 下标为i-k/2的数会从1变成0, 若变化后增量全是负值, 此时保持原值更优, 也就是增量和0取最大值

using ll = long long;
class Solution {
public:long long maxProfit(vector<int>& prices, vector<int>& strategy, int k) {ll tot = 0, sum = 0;for (int i = 0; i < k / 2; i++) {int p = prices[i], s = strategy[i];tot += p * s;sum -= p * s;}for (int i = k / 2; i < k; i++) {int p = prices[i], s = strategy[i];tot += p * s;sum += p * (1 - s);}ll max_sum = max(sum, 0LL);for (int i = k; i < prices.size(); i++) {int p = prices[i], s = strategy[i];tot += p * s;sum += p * (1 - s) - prices[i - k / 2] +prices[i - k] * strategy[i - k];max_sum = max(max_sum, sum);}return max_sum + tot;}
};
// [i,i+k/2-1]/[i-k,i-k/2-1] - 前k/2
// [i-k/2,i-1]

 2. 区间乘法查询后的异或 I

给你一个长度为 n 的整数数组 nums 和一个大小为 q 的二维整数数组 queries,其中 queries[i] = [li, ri, ki, vi]。

对于每个查询,按以下步骤执行操作:

设定 idx = li。
当 idx <= ri 时:
更新:nums[idx] = (nums[idx] * vi) % (109 + 7)
将 idx += ki。
在处理完所有查询后,返回数组 nums 中所有元素的 按位异或 结果。

解题思路:

0 <= li <= ri < n
1 <= q == queries.length <= 10^3

n*q的时间复杂度, 直接按题意模拟即可

const int MOD = 1e9 + 7;
using ll = long long;
class Solution {
public:int xorAfterQueries(vector<int>& nums, vector<vector<int>>& queries) {vector<ll> nums_;for (int i = 0; i < nums.size(); i++)nums_.push_back(nums[i]);for (int i = 0; i < queries.size(); i++) {int x = queries[i][0], y = queries[i][1], z = queries[i][2],e = queries[i][3];for (int j = x; j <= y; j += z) {nums_[j] = (nums_[j] * e) % MOD;}}ll ans = 0;for (int i = 0; i < nums_.size(); i++) {ans = ans ^ nums_[i];}return ans;}
};

3. 删除可整除和后的最小数组和

给你一个整数数组 nums 和一个整数 k。

你可以 多次 选择 连续 子数组 nums,其元素和可以被 k 整除,并将其删除;每次删除后,剩余元素会填补空缺。
返回在执行任意次数此类删除操作后,nums 的最小可能 和。

解题思路:DP,每次删除的元素和都是k的倍数, 对于数组的最后一个元素nums[n-1], 删除的话, 寻找当前待删子数组的左端点i, 下标i...n-1是k的倍数, 删除子数组 [i,n−1] 后,问题变成前缀 [0,i−1] 的最小和, 可能有多个满足条件的左端点i, 题中求删除后nums的最小可能和, 因此删除和最大的子数组和, 保留剩下最小的数组和。状态转移时, 不删就是f+x, 删的话, 变为剩余前缀的最小值

using ll = long long;
class Solution {
public:long long minArraySum(vector<int>& nums, int k) {vector<ll> a(k, LLONG_MAX);a[0] = 0;ll f = 0;int s = 0;for (int i = 0; i < nums.size(); i++) {s = (s + nums[i]) % k;f = min(f + nums[i], a[s]);a[s] = f;}return f;}
};

4. 区间乘法查询后的异或 II

给你一个长度为 n 的整数数组 nums 和一个大小为 q 的二维整数数组 queries,其中 queries[i] = [li, ri, ki, vi]。
对于每个查询,需要按以下步骤依次执行操作:

设定 idx = li。
当 idx <= ri 时:
更新:nums[idx] = (nums[idx] * vi) % (109 + 7)。
将 idx += ki。
在处理完所有查询后,返回数组 nums 中所有元素的 按位异或 结果。

解题思路:大数据范围 - 不会写 - 转载佬的

如果 ki​>n​,我们直接暴力计算,因为下标每次增加 n​,最多加 n​ 次就到 n 了。维护这种操作的复杂度是 O(qn​)。

如果 ki​≤n​,注意到本次操作被修改的下标 modki​ 都和 li​modki​ 相等,又因为只要求最后的答案,所以我们可以把这个信息先分类记下来:步长为 ki​,且下标 modki​ 为特定值,且位于区间 [li​,ri​] 里的所有下标都要乘以 vi​。步长只有 n​ 种,每种步长的 mod 也只有 n​ 种,因此我们只有 O(n) 类信息要记录。

怎么把我们记录的信息还原成答案呢?我们枚举每类信息,这样问题变为:每次给一个区间乘以 vi​,问每个数最后的值。这就是 leetcode 1109. 航班预定统计,对操作区间排序,使用差分 + 扫描线的思想即可离线处理。1109 题里,加法的逆运算是减法,本题里模意义下乘法的逆运算是求逆元。

还原答案的复杂度是多少呢?注意到相同步长不同余数的下标是不会重复的,因此每种步长会恰好把所有下标枚举一遍,因此我们会枚举 O(nn​) 次下标,再加上对操作的排序,因此复杂度为 O(qlogq+nn​)。

最后考虑求逆元的复杂度,整体复杂度为 O(q(logq+logM)+nn​),其中 M=109+7 是模数。

class Solution {
public:int xorAfterQueries(vector<int>& nums, vector<vector<int>>& queries) {int n = nums.size(), B = sqrt(n);// 求乘法逆元const int MOD = 1e9 + 7;auto inv = [&](long long a) {long long b = MOD - 2, y = 1;for (; b; b >>= 1) {if (b & 1) y = (y * a) % MOD;a = a * a % MOD;}return y;};long long A[n];for (int i = 0; i < n; i++) A[i] = nums[i];typedef pair<int, long long> pil;vector<pil> vec[B + 1][B + 1];for (auto &qry : queries) {int l = qry[0], r = qry[1], K = qry[2], v = qry[3];if (K <= B) {// 步长不超过根号,先把操作记下来// 差分思想:记录操作开始的位置以及原运算,再记录操作结束的位置以及逆运算vec[K][l % K].push_back({l, v});vec[K][l % K].push_back({r + 1, inv(v)});} else {// 步长超过根号,暴力处理for (int i = l; i <= r; i += K) A[i] = A[i] * v % MOD;}}// 枚举每一类操作for (int k = 1; k <= B; k++) for (int m = 0; m < k; m++) {// 把操作按下标从左到右排序sort(vec[k][m].begin(), vec[k][m].end());// 扫描线维护当前乘积long long now = 1;// 枚举这一类里的所有下标for (int i = m, j = 0; i < n; i += k) {// 用扫描线进行需要的操作while (j < vec[k][m].size() && vec[k][m][j].first <= i) {now = now * vec[k][m][j].second % MOD;j++;}A[i] = A[i] * now % MOD;}}long long ans = 0;for (int i = 0; i < n; i++) ans ^= A[i];return ans;}
};

感谢大家的点赞和关注,你们的支持是我创作的动力!

 

http://www.dtcms.com/a/346879.html

相关文章:

  • 两款快速启动软件下载及安装!(GeekDesk和Lucy)!可图标归类!桌面更简洁
  • eBay运营全链路解析:从售后风控到生命周期营销的效率革命
  • 软件测试从入门到精通:通用知识点+APP专项实战
  • 基于STM32设计的养殖场环境监测系统(华为云IOT)_267
  • 8月23日星期六今日早报简报微语报早读
  • 施工场景重型车辆检测识别数据集(挖掘机、自卸卡车、轮式装载机):近3k图像,yolo标注
  • 奇怪的前端面试题
  • UDP报文的数据结构
  • Python训练营打卡Day41-Grad-CAM与Hook函数
  • 【亲测可用】Suno-API 调用使用指南
  • GEO优化服务引领AI时代营销变革 “AI黄金位”成企业竞争新焦点
  • Leetcode—931. 下降路径最小和【中等】
  • Nginx 优化(一)
  • 百度面试题:赛马问题
  • 小迪安全v2023学习笔记(七十讲)—— Python安全SSTI模板注入项目工具
  • 容器安全实践(三):信任、约定与“安全基线”镜像库
  • 博士招生 | 美国圣地亚哥州立大学 Yifan Zhang 课题组博士招生,AI 安全领域顶尖平台等你加入!
  • 使用 LangChain 和 Neo4j 构建知识图谱
  • Linux docker上部署Dify
  • Linux服务环境搭建指南
  • 第四十三天(JavaEE应用ORM框架SQL预编译JDBCMyBatisHibernateMaven)
  • 海外媒体引流进阶:指纹手机的全维度技术支持与实践应用
  • ​崩坏世界观中的安全漏洞与哲学映射:从渗透测试视角解构虚拟秩序的脆弱性​
  • Base64编码、AES加密、RSA加密、MD5加密
  • 基于大模型的对话式推荐系统技术架构设计
  • 【K8s】整体认识K8s--K8s架构与集群创建过程
  • Doxygen是什么?
  • 多模态大语言VLM模型综述
  • 【GPT入门】第56课 大模型分布式训练的三种方式、模型层介绍及DeepSpeed ZeRO的支持
  • 《Linux》基础命令到高级权限管理指南