Educational Codeforces Round 95题解

题目链接

代码链接

A. Buying Torches

题目大意:

你手上现在有一个木棍。有以下两种交换方式:

1.用一个木棍交换xxx个木棍

2.用yyy个木棍交换111个煤

你现在想生产出kkk个火把,每个火把需要111个木棍和111个煤,问最少完成多少次交换,才能生产出kkk个火把

数据范围:2≤x≤109,2≤x≤109;1≤y,k≤1092 \leq x \leq 10^9,2 \leq x \leq 10^9; 1 \leq y,k \leq 10^92≤x≤109,2≤x≤109;1≤y,k≤109

题解:

因为最后需要kkk个火把,即需要kkk个煤,所以需要y×ky\times ky×k个木棍用于第二种交换方式

最后还需要kkk个木棍用于做火把,所以一共需要y×k+ky \times k + ky×k+k个木棍

每次使用第一种交换方式,手上的木棍会多出x−1x-1x−1个,所以第一种交换需要进行至少⌈y×k+kx−1⌉\lceil \frac{y \times k + k}{x-1} \rceil⌈x−1y×k+k​⌉

第二种交换需要进行kkk次,所以答案为$\lceil \frac{y \times k + k}{x-1} \rceil + k $

B. Negative Prefixes

题目大意:

给定一个长度为nnn的序列,其中一些位置是固定的,你可以任意交换不固定的位置的数。要求最终序列的前缀和序列中,最后一个负值的下标最小。

数据范围:1≤n≤100,−105≤ai≤105)1≤n≤100,−10^5≤a_i≤10^5)1≤n≤100,−105≤ai​≤105)

题解:

设原序列为ana_nan​

考虑交换两个未固定位置的两个数对于前缀和序列的影响。假设两个数的下标是iii和jjj,那么前缀和序列中,下标比iii小的和比jjj大的将不变。

而前缀和序列中下标在iii和jjj之间的数

​ 如果ai>aja_i>a_jai​>aj​,则将全部减小,答案可能变劣,因为最后一个负值的下标一定是不变或者向后移动

​ 如果ai<aja_i<a_jai​<aj​,则将全部增大,答案可能变优,因为最后一个负值的下标一定是不变或者向前移动

所以,

我们直接对所有未固定的位置的数按从大到小排序再按顺序填回去即可。

C. Mortal Kombat Tower

题目大意:

你和你的朋友在玩一款游戏,现在有nnn个boss依次排在你们的面前。你和你的朋友轮流打怪(你的朋友先打),每人每次可以打1到2个怪(不能不打)。怪分为普通怪和精英怪,你的朋友比较弱,每次打精英怪的时候需要使用必杀技。而你比较强,精英怪和普通怪都乱杀。现在希望你朋友用必杀技的次数越少越好,问你的朋友最少需要使用多少次必杀技。ai=0a_i=0ai​=0代表普通怪,ai=1a_i=1ai​=1代表精英怪。

数据范围:1≤n≤2⋅1051≤n≤2⋅10^51≤n≤2⋅105

题解:

动态规划,首先设定状态

dp(i,0)dp(i,0)dp(i,0)表示前iii个怪打完了,最后一个怪是你打的,这时最少使用的必杀技次数

dp(i,1)dp(i,1)dp(i,1)表示前iii个怪打完了,最后一个怪是你朋友打的,这时最少使用的必杀技次数

转移方程

每次转移只用考虑是打一个更优还是打两个更优即可

dp(i,0)=min(dp(i−1,1),dp(i−2,1))dp(i,0)=min(dp(i-1,1),dp(i-2,1))dp(i,0)=min(dp(i−1,1),dp(i−2,1))

dp(i,1)=min(dp(i−1,0)+a[i],dp(i−2,0)+a[i]+a[i−1])dp(i,1)=min(dp(i-1,0)+a[i],dp(i-2,0)+a[i]+a[i-1])dp(i,1)=min(dp(i−1,0)+a[i],dp(i−2,0)+a[i]+a[i−1])

注意一下边界。

D. Trash Problem

题目大意:

有nnn堆石子,每堆石子的位置在pip_ipi​。每次操作可以选择某一堆石子,将其向左或向右移动一格。当两堆石子移动到同一个位置的时候他们就会合并成一堆,问最少需要移动多少次,使得最终只有最多两堆石子。

之后有q组询问,每次会在xix_ixi​的位置新增一堆石子或者将xix_ixi​位置 的石子去除,同样问上述的问题。

保证新增石子的时候该位置没有石子,去除石子的时候该位置一定有石子,并且前面的操作会对后面的产生影响,即不是操作完还原。

数据范围:1≤n,q≤105,1≤pi,xi≤1091≤n,q≤10^5,1≤p_i,x_i≤10^91≤n,q≤105,1≤pi​,xi​≤109

题解:

由于最后可以合并成至多两堆石子,所以并不需要把所有石子合并到一起。

那么可以想象答案是max(pi)−min(pi)−max(pi−pi−1)max(p_i)-min(p_i)-max(p_i-p_{i-1})max(pi​)−min(pi​)−max(pi​−pi−1​),即找到一段最大的间隔,左边的石子合并成一堆,右边的石子合并成一堆。

我们用一个setsetset维护石子的位置,一个multisetmultisetmultiset维护间隔。

每次加入一堆石子,setsetset中加入这堆石子并维护multisetmultisetmultiset中的间隔

auto it = pos.find(x);

找pos中前面石子堆位置的和后面的石子堆位置的时候,可以使用prev(it)prev(it)prev(it)和next(it)next(it)next(it)。如果编译器不支持,可以写成:

int Prev(auto it, int k=1){while (k--) it--; return *it;}
int Next(auto it, int k=1){while (k--) it++; return *it;}

这个是找前面第kkk个和后面第kkk个(kkk比较小的时候)

E. Expected Damage

题目大意:

有nnn个怪物,每个怪物的攻击力为did_idi​。现在你有aaa层盾,每层盾的防御力为bbb。

当怪物攻击时

​ 如果没有盾,你会掉bbb的血;

​ 如果有盾但d>=bd>=bd>=b,你会被打掉一层盾;

​ 如果有盾但d<bd<bd<b,则没有影响;

问怪物随机排列来攻击你,你掉血量的期望;有多次询问,每次给出不同的aaa和bbb。

数据范围:1≤n,m≤2⋅105,1≤di,b≤109,1≤ai≤n1≤n,m≤2⋅10^5,1≤d_i,b≤10^9,1≤a_i≤n1≤n,m≤2⋅105,1≤di​,b≤109,1≤ai​≤n

题解:

题目的是要求总共伤害的期望,我们可以计算每个怪物对我们造成伤害量的期望,再求和。

考虑每个怪物什么时候可以造成伤害,造成伤害的条件为盾打完了。

那么每个怪能打到人的情况就是在他之前有至少aaa个怪的攻击力大于或等于bbb

对于每个输入的aaa和bbb,二分找到攻击力比bbb小的部分和比bbb大的部分

对于小的部分,我们需要前面至少有aaa个攻击力比bbb大的,假设总共有k(k>=a)k(k>=a)k(k>=a)个攻击力比bbb大的,那么,

​ 概率为k+1−ak+1\frac{k+1-a}{k+1}k+1k+1−a​,因为我们考虑攻击力比bbb大的以及当前这个的全排列,当前这个必须排在后k+1−ak+1-ak+1−a个才能造成伤害。

同理对于大的部分,其造成伤害的概率为k−ak\frac{k-a}{k}kk−a​,最后加权求和即可。

F. Equal Product

题目大意:

1≤x1<x2≤n1 \leq x_1 < x_2 \leq n1≤x1​<x2​≤n

1≤y2<y1≤m1 \leq y_2 < y_1 \leq m1≤y2​<y1​≤m

x1⋅y1=x2⋅y2x_1 \cdot y_1 = x_2 \cdot y_2x1​⋅y1​=x2​⋅y2​

l≤x1⋅y1≤rl \leq x_1 \cdot y_1 \leq rl≤x1​⋅y1​≤r

输入n,m,l,rn,m,l,rn,m,l,r,对于每个x1x_1x1​(1≤x1≤n1 \leq x_1 \leq n1≤x1​≤n)输出一组满足上述条件的整数解,或者无解输出−1-1−1

数据范围:1≤n,m≤2⋅105,1≤l≤r≤nm1≤n,m≤2⋅10^5,1≤l≤r≤nm1≤n,m≤2⋅105,1≤l≤r≤nm

题解:

因为x1⋅y1=x2⋅y2x_1 \cdot y_1 = x_2 \cdot y_2x1​⋅y1​=x2​⋅y2​,所以我们设

x2=x1⋅bax_2=x_1 \cdot \frac{b}{a}x2​=x1​⋅ab​,那么有y2=y1⋅aby_2=y_1\cdot \frac{a}{b}y2​=y1​⋅ba​

我们预处理出所有的x1x_1x1​和他的因子aaa,枚举每个点对(x1,a)(x_1,a)(x1​,a)

对于每个点(x1,a)(x_1,a)(x1​,a),y1y_1y1​的限制为⌈lx1⌉≤y1≤min(m,⌊rx1⌋)\lceil \frac{l}{x_1} \rceil \leq y_1 \leq min(m, \lfloor\frac{r}{x_1} \rfloor)⌈x1​l​⌉≤y1​≤min(m,⌊x1​r​⌋)

接着我们确定b的限制

因为x1<x2x_1 < x_2x1​<x2​ ,所以b>ab>ab>a

因为x2≤nx_2 \leq nx2​≤n,所以b≤n⋅ax1b \leq \frac{n \cdot a}{x_1}b≤x1​n⋅a​

同时我们要求bbb是y1y_1y1​的因子

我们从小到大枚举x1x_1x1​,固定x1x_1x1​后从小到大枚举aaa

x1x_1x1​确定后,我们可以确定y1y_1y1​的取值范围,是一个区间,并且区间随着x1x_1x1​的增大会在数轴上向左移动

我们维护这个区间中所有数的因子,每次枚举aaa的时候,我们可以确定bbb的一个区间。

现在我们需要快速知道y1y_1y1​对应的区间中是否有一个数是bbb对应的区间中一个数的倍数

我使用的是线段树维护,线段树的叶子节点为因子,维护该因子在y1y_1y1​区间中对应的哪个值,即哪个值是含有该因子的。我们可以只记录最小的那个值,因为区间是向左移动的。查询时就bbb对应的因子区间是否含有合法的y1y_1y1​。

G. Three Occurrences

题目大意:

给定一个长度为nnn的序列,问该序列中有多少个子串,使得其中相同的数恰好出现三次

数据范围:1≤n≤5⋅105,1≤ai≤n1≤n≤5⋅10^5,1≤a_i≤n1≤n≤5⋅105,1≤ai​≤n

题解:

cf给的题解很巧妙,复述一下。

首先考虑第一个问题:如何找到有多少子串,使得其中相同的数出现的次数是三的倍数

我们给每个数随机给他一个长度为KKK的序列,这个序列中的只包含0,1,2。然后定义一个三进制下的无进位加法。这样的话,三个完全相同的序列相加,将得到一个全0的序列。

而只要KKK比较大,以下结论的正确率就会很高。
结论:如果mmm个序列相加为全0序列,那么这mmm个序列对应的mmm个数中,相同的数出现的次数就是三的倍数。

那么我们可以使用mapmapmap维护出某个前缀和(这里的前缀和指的是数字对应序列的前缀和)的个数,枚举右端点,在mapmapmap中找到与当前前缀和相同的前缀和有多少个。

第二个问题:如何找到有多少子串,使得其中相同的数出现的次数<=3

这个使用双指针的做法,枚举右指针的位置,维护序列中每个数的出现次数,如果出现次数>=4>=4>=4了,就移动左指针,知道该数的次数<=3<=3<=3。

综合上述两个问题,双指针维护出现次数,移动指针的时候维护mapmapmap,在mapmapmap中维护前缀和出现次数即可

建议大家去读下Solution 1 (pikmike)的代码,写的很漂亮

Educational Codeforces Round 95题解相关推荐

  1. Educational Codeforces Round 95 (Rated for Div. 2)

    昨天本来想打一下,但是今天早上课很早,就没有打,只是看了看前三个题写了个代码,今天中午课结束交了一下都AC了.y1s1 A题第一次写就出来了,但是答案一直不对,最后结果是样例错了-.- A - Buy ...

  2. Educational Codeforces Round 95 (Rated for Div. 2)D. Trash Problem(权值线段树+离散化)

    题目描述 Vova decided to clean his room. The room can be represented as the coordinate axis OX. There ar ...

  3. Educational Codeforces Round 76 (Rated for Div. 2) 题解

    Educational Codeforces Round 76 题解 比赛链接 A. Two Rival Students #include<bits/stdc++.h> using na ...

  4. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  5. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  6. Educational Codeforces Round 140 (Rated for Div. 2)题解

    看看时间还有十几分钟,开不出来题了,写个题解 A. Cut the Triangle 检查是不是直角边平行于坐标轴的直角三角形即可 这里可以用异或来写,代码较为简洁,我就不改了,直接贴上我的丑代码 c ...

  7. Educational Codeforces Round 133 (Rated for Div. 2)(CD题解)

    Educational Codeforces Round 133 (Rated for Div. 2)CD题解 过AB补CD C. Robot in a Hallway 题意 题意:现有 2∗m 的方 ...

  8. Educational Codeforces Round 104 (Rated for Div. 2)A-E题解

    Educational Codeforces Round 104 (Rated for Div. 2)A-E题解 比赛链接:https://codeforces.ml/contest/1487 A题 ...

  9. Educational Codeforces Round 112(Div.2) ABC题解

    D题好像可以做一做,挖个坑以后做好了来填(doge Educational Codeforces Round 112(Div.2) 题目列表 1.A 2.B 3.C 1.A 原题链接 题目大意 有三种 ...

最新文章

  1. Java技术——Iterator和Enumeration的不同
  2. 一款直击痛点的优秀http框架,让我超高效率完成了和第三方接口的对接
  3. 文巾解题 203. 移除链表元素
  4. 分享10个jQuery页面动态编辑插件
  5. 2022年最值得学习的 5 种编程语言,你有在学习吗?
  6. 工作337:pc-ele-ment联查问题
  7. python做数据和大数据区别_不懂Python,不懂大数据的人,和咸鱼有什么区别?
  8. 创建django项目,8月版本
  9. linux系统usb口死机,在Linux上修复故障的USB设备或端口的5种方法 | MOS86
  10. matlab画直方图
  11. 微信公众号开发详细笔记
  12. Android6.0权限的处理
  13. iPhone/iPad怎么进入恢复模式?
  14. H5viedo标签播放*.Mp4听得到音频却不显示视频的解决办法
  15. 二维码扫描枪中文开发指导
  16. 裸金属服务器与云服务器的差别是什么?
  17. 如何用wireshark来解析出PDCP-LTE格式,即把PDCP报文突出到wireshark
  18. 华为Linux改装windows的弊端,试用华为的linux版电脑,不安装windows,能不能胜任工作? - 区块网...
  19. Android aab文件签名过程
  20. python中and和or的区别-Python中and-or语法

热门文章

  1. oracle分区表优点
  2. MAX7219产品级驱动分享
  3. UID GID 说明及例子
  4. C/C++动态数组delete时卡死或报错解决
  5. mac下用户用户组命令行操作
  6. oracle函数之NULLIF
  7. 回顾 2022 年 — 回顾 Elastic 这一年
  8. (JAVA编程练习):输入某年某月某日,判断这一天是这一年的第几天?
  9. div和span的标签属性及说明
  10. 对象存储OSS之阿里云OSS介绍及开通