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

题解:P11709 「KTSC 2020 R2」魔法转盘

将环复制两遍拼在前面和后面,转化为序列上的问题。

考虑一个暴力做法。枚举最后点对齐到第 \(i\) 列上,那么每一行肯定是将第 \(i\) 列左边第一个点或者右边第一个点转过来。这样可以直接二分做到 \(\mathcal O(MR\log n)\)。也可以对 \(i\) 扫描线加上一点手法做到 \(\mathcal O(MR)\)

进一步,枚举第 \(i\) 列后,相当于第 \(j\) 行得到 \(l_j,r_j\),求 \(\sum_{j=1}^M\min(|i-l_j|,|i-r_j|)\)。假如 \(i\) 没有取到任何一个 \(l_j,r_j\),设此时上面的 \(\min\)\(c\) 个取到 \(|i-l_j|\),另外 \(M-c\) 个取到 \(|i-r_j|\),那么在 \(c\ge\frac{M}{2}\) 时取第 \(i-1\) 列不劣,在 \(c<\frac{M}{2}\) 时取第 \(i+1\) 列不劣。所以只需要考虑出现的点的列 \(i\),复杂度将为 \(\mathcal O(M\min(N,R))\)

继续优化。对于第 \(j\) 行,考虑每对相邻的点 \((l,r)\),设 \(mid=\lfloor\frac{l+r}{2}\rfloor\),则在 \(i\in[l,mid]\) 时上面的和式第 \(j\) 项会取 \(i-l\),在 \(i\in[mid+1,r]\) 时会取 \(r_j-i\)。这可以转化为在所有点的纵坐标离散化后的数组上进行区间加,不难差分解决。

总复杂度 \(\mathcal O(N\log N)\),需要排序和二分。

参考代码:

#include <bits/stdc++.h>
typedef long long LL;
typedef unsigned long long ULL;
typedef std::pair<int, int> pii;
typedef std::pair<int, LL> pil;
typedef std::pair<ULL, ULL> puu;
#define fi first
#define se second
#define MP std::make_pair
#define EB emplace_backlong long findMinClicks(int M, int R, std::vector <std::pair<int, int> > P);const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fll;
template<typename T> void Fmin(T &x, T y){ if (y < x) x = y; }
template<typename T> void Fmax(T &x, T y){ if (x < y) x = y; }const int MAXN = 500005;
int tmp[MAXN], V, cnt[MAXN]; 
LL sum[MAXN];
std::vector<int> a[MAXN];
void addL(int l, int r, int v)
{if (l > r) return ;l = std::lower_bound(tmp + 1, tmp + V, l) - tmp;r = std::upper_bound(tmp + 1, tmp + V, r) - tmp;cnt[l]++, cnt[r]--, sum[l] -= v, sum[r] += v;
}
void addR(int l, int r, int v)
{if (l > r) return ;l = std::lower_bound(tmp + 1, tmp + V, l) - tmp;r = std::upper_bound(tmp + 1, tmp + V, r) - tmp;cnt[l]--, cnt[r]++, sum[l] += v, sum[r] -= v;
}
LL findMinClicks(int n, int m, std::vector <std::pair<int, int> > P) 
{if (m == 1) return 0;V = 0;for (pii p : P) tmp[++V] = p.se + 1, a[p.fi + 1].push_back(p.se + 1);std::sort(tmp + 1, tmp + V + 1);V = std::unique(tmp + 1, tmp + V + 1) - tmp;for (int i = 1; i <= n; i++){std::sort(a[i].begin(), a[i].end());for (int j = 0; j + 1 < a[i].size(); j++){int l = a[i][j], r = a[i][j + 1];int mid = (l + r) >> 1;addL(l, mid, l), addR(mid + 1, r - 1, r);}int l = a[i].back(), r = a[i][0];int mid = ((LL)l + (r + m)) >> 1;if (mid <= m){addL(l, mid, l);addR(mid + 1, m, m + r);addR(1, r - 1, r);}else{addL(l, m, l);addL(1, mid - m, l - m);addR(mid - m + 1, r - 1, r);}}LL ans = INF;for (int i = 1; i < V; i++){cnt[i] += cnt[i - 1], sum[i] += sum[i - 1];Fmin(ans, (LL)cnt[i] * tmp[i] + sum[i]);}return ans;
}
http://www.jsqmd.com/news/93541/

相关文章:

  • FAQ12118:关于修改底色为白色后,设置中菜单字体显示为灰色字体问题(白底黑字)
  • 运维系列数据库系列【仅供参考】:达梦数据库大内存SQL定位和监控
  • Hoppscotch批量编辑完全指南:从基础到精通的高效参数管理
  • 【更新至2024年】2006-2024年上市公司彭博esg评分数据(含细分项)
  • matlab基于词典的稀疏表示高光谱图像分类
  • 20、Java交互与图形编程及DOS系统发展全解析
  • 基控电箱是什么?功能、选型与应用全指南
  • 达尔文12号在哪买:权威榜单与专业选购指南 - 品牌测评家
  • 开源AI新宠LobeChat:支持多模型切换的聊天界面解决方案
  • AutoGPT开源镜像发布:让AI自己完成你的工作目标
  • 闸机租赁源头厂家揭秘,哪家实力最强? - 真知灼见33
  • 步骤详图 教你在linux搭建容器环境
  • PAT 1145 Hashing - Average Search Time
  • Postman接口测试之postman设置接口关联,实现参数化
  • 论文研究内容怎么写?最强技巧让导师直接点头通过
  • 自动化工程:赋能产业升级的核心引擎,从原理到应用全解析
  • AutoGPT在文化遗产数字化保护中的作用探讨
  • Ubuntu20.04安装Miniconda并配置GPU版PyTorch全流程
  • 收藏必备!Agentic RAG:从RAG到Agent的智能进化之路
  • 中国2000-2024年500m分辨率逐月叶面积指数(LAI)数据集
  • 收藏!35岁程序员转大模型:合适吗?前景与落地指南
  • 5、编程中的函数、参数传递与数组应用
  • 【收藏必看】2025大模型技术岗位全景图:15大方向详解,助你成为AI人才
  • 光刻胶增感剂用4-羟基二苯基碘鎓盐
  • 光刻胶增感剂用全氟丁基磺酸盐
  • IPv6过渡技术:从双栈到自动隧道
  • 如何设计高可靠环境监控系统?从“五重告警机制”看现代以太网温湿度传感器的告警架构
  • LobeChat为何成为GitHub热门项目?核心优势全面剖析
  • 计算机毕业设计springboot舞蹈室管理系统 基于 SpringBoot 的舞蹈培训机构综合运营平台 SpringBoot 框架下的舞蹈教室智慧排课与学员服务系统
  • 企业AI落地关键一步:vLLM生产级推理部署方案