1 条题解
-
0
题意
- 有 n 个怪物,第 i 个怪物存活于时刻区间 ,具有攻击力
- 选择一个非负整数时刻 x 发出攻击,可以攻击到 这些时刻
- 如果某个怪物的存活区间中没有遭受过任何攻击,那么其就会造成对应 的破坏
- 求选择哪一个非负整数时刻 进行攻击,能够使得攻击的怪物破坏总和最低,输出这个总和
思考
- 重要结论一:x 只可能在区间 中选择
- 如果选择了一个超过 的 ,也就是说
- 那么选择 一定不会变差
- 因为选择 能够攻击到:
- 其包含了选择 进行攻击时能够攻击到的所有时刻,所以答案不会变差
- 重要结论二:对于存活区间长度超过 的怪兽,其不管选择什么时刻攻击都能干掉它
- 可以发现如果区间长度超过 ,那么其必然包含了 的所有余数
- 所以不论选择 的哪个时刻发起攻击,都能够干掉这个怪兽
部分分
- 特殊性质 1:(20 分)
- 直接枚举发起攻击的时刻
- 再在 中把被攻击到的点都标记
- 然后计算每一个区间 是否被枚举的攻击时刻攻击
- 直接扫描区间 中是否有被攻击到的点即可
- 取没被攻击怪兽伤害值总和最小的作为答案
- 时间复杂度:
- 直接枚举发起攻击的时刻
- 特殊性质 2:(30 分)
- 没有特殊解
题解
- 可以发现能够发出攻击的区间只需要考虑
- 那么很自然想法,将每一只怪兽的存活区间,映射到 中,看从哪些位置发出攻击能够干掉这只怪兽
- 对于长度超过 的怪兽区间,直接默认死亡(不予考虑)
- 对于长度小于 的区间将其平移到 以内
- 且
- 分情况讨论,若现在
- 那么说明在 间发起攻击能够干掉一只 的怪兽
- 若现在
- 那么说明在 和 这两个区间中发起攻击能够干掉一只 的怪兽
- 前缀和统计 的每一个时刻能够消灭多少攻击力的怪兽取最大值减去即可
code
const int N = 1e5 + 9; int sum[N]; void solved() { // 共 n 个怪物,每隔 m 单位时间攻击一次 int n, m; cin >> n >> m; int s = 0; while(n --) { // 当前怪物存活于 [l, r],攻击力为 w int l, r, w; cin >> l >> r >> w; // 如果存活区间长度至少为 m,这个怪物一定会死亡,无需考虑 if(r - l + 1 >= m) continue; s += w; l %= m, r %= m; if(l <= r) sum[l] += w, sum[r + 1] -= w; else sum[0] += w, sum[r + 1] -= w, sum[l] += w, sum[m] -= w; } // 计算前缀和 int mx = 0; for(int i = 0; i <= m - 1; i ++) { if(i != 0) sum[i] += sum[i - 1]; mx = max(mx, sum[i]); } cout << s - mx; return ; }
- 1
信息
- ID
- 162
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 35
- 已通过
- 5
- 上传者