HNOI做题记录
算是……咕完了?
2013、2014的就咕了吧,年代太久远了,并且要做的题还有那么多……
LOJ #2112. 「HNOI2015」亚瑟王
发现打出的概率只和被经过几次有关。
于是\(dp_{i,j}\)表示第\(i\)张卡被考虑\(j\)次的概率,随便转移。
LOJ #2113. 「HNOI2015」接水果
脑子没了,这题都不会做??
考虑\((x,y)\in (a,b),lca(x,y)\ne x\)就等价于\(dfn_a\in [dfn_x,low_x],dfn_b\in [dfn_y,low_y]\),如果\(lca(x,y)=x\)就特殊处理一下,于是盘子变成矩形,水果变成点。
整体二分就没了。
LOJ #2114. 「HNOI2015」菜肴制作
经典套路,每次把能放最后的最大的往最后丢即可。
为什么?如果不是这样的话就把\(max\)后面的整体前移,\(max\)丢到最后,这样一定合法并且更优。
LOJ #2115. 「HNOI2015」落忆枫音
如果就只是给一个DAG的话就很好做,只需要每个点任意指定一个父亲即可。
考虑加了一条边\((x,y)\)(先把自环给判掉),那么强制这条边必选。如果除\(y\)以外的点仍然任意选父亲,那么就有可能出现环,要被删掉。考虑环除了\((x,y)\)边以外就只剩一个\(y\to x\)的链了,随便dp一下就可以了。
LOJ #2116. 「HNOI2015」开店
经典套路。
LOJ #2117. 「HNOI2015」实验比较
可以注意到缩点之后必然会是一个森林,我们再建一个虚点把根连过去,变成一棵树。
显然是设\(dp_{i,j}\)表示子树\(i\)分成\(j\)段的方案数,考虑如何合并子树。假设长度分别是\(i,j\),要合成\(k\),那么方案数就是\({k \choose i}\times {i\choose i+j-k}\),意思是先给\(i\)个分配位置,然后再选出一些合并两段的位置,剩下的位置就唯一确定了。
当然,我这种没智商的人是想不到这样做的,于是就只会预处理\(f_{i,j,k}\),但复杂度其实还是\(O(n^4)\)。
(但是上面那个这么像树形背包的东西恐怕是\(O(n^3)\)的?)
LOJ #2048. 「HNOI2016」最小公倍数
分块,写过了:https://www.cnblogs.com/p-b-p-b/p/10391114.html。
LOJ #2049. 「HNOI2016」网络
一种暴力是插入路径的时候利用树剖把它插到其他点的堆里面,线段树维护,是\(O(n\log^3 n)\)的。
考虑二分答案,看经过这个点的路径数和所有的路径数是否相等。
如何求经过一个点、大于某个值的路径数?差分+树套树。
这样是时间\(O(q\log^3 n)\)、空间\(O(q\log^2 n)\)的,把树套树外层开成值域然后线段树上二分大概可以把时间变成\(O(q\log^2 n)\)的,然而空间还是炸了。
考虑整体二分,你发现不用树套树而是一个树状数组就做完了。
LOJ #2050. 「HNOI2016」树
考虑将每次copy过去的子树看作一个大节点,相邻两个大节点的距离是根之间的距离。
然后就只需要维护某个点对应回原树是哪个节点了。这个数据结构随便维护一下就没了。
据说代码很难写。你看我像是会写代码的鸽子吗?
LOJ #2051. 「HNOI2016」序列
口胡。
显然是考虑每个点作为最小值的贡献。先把区间最小值的贡献算出来。
考虑区间最小值右边那一段。设\(r_i\)表示右边第一个小于自己的位置,\(l_i\)同理。
如果\(r_i\le r\),那么\(i\)的贡献显然已经与\(r\)无关了。如果\(r_i>r\),那么还需要在原来的基础上减去\(a_i\times (i-l_i) \times (r_i-r)\),把最后一个括号拆开之后似乎也是很好求的。
于是主席树大概就可以了?
LOJ #2052. 「HNOI2016」矿区
咕了。
LOJ #2053. 「HNOI2016」大数
先把\(P=2,P=5\)的判掉,然后做一个\(a_i\times 10^{n-i}\)的后缀和,就变成了区间相同数的对数。
莫队直接上。
LOJ #2018. 「AHOI / HNOI2017」单旋
插入一个点的时候必然只会放在前驱的右儿子或后继的左儿子,取决于谁的深度更深,所以还是只需要维护深度。
单旋最小值\(x\)时可以发现除了右子树不变、\(x\)深度变为1以外深度全都+1,而只需要知道\(fa_x\)就可以知道右子树有哪些点。
发现维护父子关系很容易,于是做完了。
LOJ #2019. 「AHOI / HNOI2017」影魔
md没发现是排列懵了好久……
考虑到两个条件都要求某一个端点是最大值,我们在最大值处统计贡献。假设最大值在右边。
从左往右扫,设左边第一个大于\(k_i\)的是\(l\),那么\((l,i)\)中间的数如果是后缀最大值则贡献\(p_1\),否则贡献\(p_2\)。
强制所有都贡献\(p_2\),然后给后缀最大值的位置再加上\(p_1-p_2\)即可。由于后缀最大值就存在单调栈里,而它们反正都是要被弹掉的,所以复杂度正确。
离线或者直接主席树大概都可以。
LOJ #2020. 「AHOI / HNOI2017」礼物
FFT模板题?
LOJ #2021. 「AHOI / HNOI2017」大佬
首先可以很容易地用DP求出除回血外最多能做的操作次数是多少。
用某些方法发现怼大佬能搞出的伤害种类不多,于是BFS求出每种伤害需要的次数。
然后由于只能怼两次,乱搞就完了。
LOJ #2022. 「AHOI / HNOI2017」队长快跑
咕咕咕。
LOJ #2023. 「AHOI / HNOI2017」抛硬币
这里采用我这种菜鸡能想出来的暴力推式子方法。
考虑答案就是
\[
\sum_{i=0}^b \sum_{j=i+1}^a {b\choose i}{a\choose j}
\]
我们先把\(j>b\)的情况暴力算出来,后面只考虑\(j\le b\)的。
那么就有
\[
\begin{align*}
ans&=\sum_{i=0}^b \sum_{j=i+1}^b {b\choose i}{a\choose j}\\
&=2^b\times S-\sum_{i=0}^b \sum_{j=0}^i {b\choose i}{a\choose j}\\
&=2^b\times S-\sum_{j=0}^b \sum_{i=j}^b {b\choose b-i}{a\choose i-j}\\
&=2^b\times S-\sum_{j=0}^b {a+b\choose j}
\end{align*}
\]
其中\(S=\sum_{i=0}^b {a\choose i}=2^a-\sum_{i=b+1}^a {a\choose i}\)。
后面这个求和式可以利用组合数的对称性,变成\(2^{a+b-1}-\frac 1 2\sum_{j=b+1}^{a-1} {a+b\choose j})\),然后后面那东西再利用对称性把\(\frac 1 2\)消掉,只有\(2|(a+b)\)的时候会多出\(\frac 1 2{a+b\choose (a+b)/2}\),扩展lucas的时候操作一下就没了。当然你也可以直接发现它是\({a+b-1\choose (a+b)/2}\)。
LOJ #2494. 「AHOI / HNOI2018」寻宝游戏
不优美的解法
考虑从后往前推。
容易发现限制相当于是前面的要凑出一个数,长成\(0110??01?10\)的样子。
如果需要凑0但这一位是1,那么只能放and;如果需要凑1但这一位是0,那么只能放or;如果每一位都对上了,那么两个都可以放。限制也可以相应地往前推。
如果出现第三种情况,那么前面就会出现\(000??0?0\)或是\(11??1?1\)的限制,即0和1只有一种。
当01只有一种的时候,可以发现往前推的时候就只有一种情况需要递归算了。以\(00??0?\)为例。若当前数是\(001001\),那么如果放and,前面的限制就会是\(??????\),也就是任意,所以只需要算or的。
bitset优化,复杂度\(O(\frac{nmq}{\omega})\)。
优美的解法
努力观察性质,按每一位考虑,每个数变成0/1。
把这些数连成一串,第\(n\)位为最高位;把第\(n\)个数前面的符号作为最高位,and看做1。
然后你惊喜地发现,如果符号连成的数小于原来的数,就会获得一个1,否则0。
于是列出一堆不等式,你就赢了。
LOJ #2495. 「AHOI / HNOI2018」转盘
以下数组下标都从0开始。
首先通过打表/严谨证明,可以发现从一个点出发最多只会转一圈,否则不优。
为什么?如果当前时间大于等于出现的时间,那么将这个物品标记是不需要时间的。如果要转很多圈,那么显然每个物品都会是最后一圈的时候拿最优,所以前面的都是废的。
然后枚举从哪个点出发,断环为链,就可以贪心地算出最短时间。
优化?用各种方法可以发现,设\(b_i=T_i-i\),那么答案就是\(n-1+\max b_i\)。
现在是\(O(n^2q)\)的。我们把\(T\)倍长,仍然设\(b_i=T_i-i\),之后就可以发现答案就是\(n-1+\min_{i=0}^{n-1} \max_{j=i}^{2n-1} b_j\)。可以做到\(O(nq)\)。
然后咋做?该上数据结构了?
考虑楼房重建的套路,设\(solve(l,r,mx)\)表示后面的最值是\(mx\),只考虑\([l,r]\)的答案。如果\(mx\ge max(mid+1,r)\),那么右儿子的答案定下来了,查左儿子;否则,左儿子的答案与\(mx\)无关,可以之前记下来,查右儿子。
然后就做完了。
LOJ #2496. 「AHOI / HNOI2018」毒瘤
很容易想到容斥:强制一些非树边不合法,相当于强制某些点必选,然后求树的方案数。
我会动态DP!
动态DP不够优美,考虑别的方法。
由于总共涉及到的点只有22个,我们把虚树建出来,在上面DP。
虚树上DP独立集个数的时候当然不能按普通树的做法写,而是要预处理出儿子对父亲的贡献系数,即\(k_0 dp_{son,0}+k_1 dp_{son,1}\)。
然后就做完了。令\(s=m-n\),复杂度\(O(s2^{s}+sn)\)。
如果用动态DP的话要注意一些细节,比如矩阵内要维护0的个数(这样才能撤销)、枚举集合不能循环枚举而是要dfs枚举,使得相邻两个集合只有一个位置需要修改。还记得格雷码吗?
LOJ #2508. 「AHOI / HNOI2018」游戏
把没有门的点缩在一起。
如果\(i\to i+1\)的钥匙比\(i\)大,那么显然是不能往前走了,连边\(i\to i+1\)。
如果\(i-1\to i\)的钥匙比\(i\)小,那么同理,连边\(i\to i-1\)。
于是搞出一个图,\(x\to y\)表示只能\(x\)转移到\(y\)。
然后暴力按拓扑序转移即可。复杂度不知为啥是对的。
LOJ #2509. 「AHOI / HNOI2018」排列
题目给的条件真是太让人难以理解了……
经过仔细分析,可以发现其实就是要求一个排列\(p\),使得在\(p\)里面\(a_i\)比\(i\)早出现,并且要求\(\sum i\times w_{p_i}\)最大。
可以理解为\([1,n]\)的数都带上了一个权值,要把他们放成一排,并且越靠后的系数越大。
我们连边\(a_i\to i\),显然构成了一棵以\(0\)为根的树,父亲比儿子早出现。
容易发现当权值最小的数可以放在最前面的时候,一定会把它放在最前面,这样显然最优。于是根据树上贪心的套路,可以把它和父亲缩在一起。
但缩在一起的连通块其实是一个序列,此时怎么比较呢?
设他们分别是\(a[1...n],b[1...m]\),那么可以列出式子:
\[
S_1=\sum_{i=1}^n iw_{a_i}+\sum_{i=1}^m (i+n)w_{b_i}\\
S_2=\sum_{i=1}^n (i+m)w_{a_i}+\sum_{i=1}^m iw_{b_i}\\
S_1-S_2=n\sum_{i=1}^m w_{b_i}-m\sum_{i=1}^n iw_{a_i}\\
S_1>S_2\Longleftrightarrow \frac 1 m\sum_{i=1}^m w_{b_i}>\frac 1 n\sum_{i=1}^n w_{a_i}
\]
(有可能系数不从1开始,但是无所谓)
所以只需要比较平均值即可。
LOJ #2510. 「AHOI / HNOI2018」道路
md,D2T3放这种题??(还是说loj编号有点锅?)
结果我tm还没做出来????
设\(dp_{x,p,q}\)表示\(x\)到根的公路和铁路有几个被修了,随便转移。
LOJ #3054. 「HNOI2019」鱼
D1T1计算几何??咕了!
LOJ #3055. 「HNOI2019」JOJO
先考虑没有可持久化怎么做。
对于每一段,我们只需要存最后那个位置的\(nxt\)指向哪里。
然而,如果它指向了一个段的中间,我们不可能在它后面加东西,所以这对后面加字符是无效的,而且我们也不想存每一段中间的\(nxt\)。
所以我们再引进一个指针\(link\),指向最长的\(border\),使得这个\(border\)最后一段是完整的。简而言之\(link\)就是把aaaa
看做一个字符a4
,然后求\(nxt\)。
此时,没有可持久化的部分就做完了:每次暴力跳\(link\)找到这一段每一部分的\(nxt\),然后继续跳\(link\)直到找到这一段结尾的\(link\)。
要可持久化呢?按照可持久化kmp的套路,我们需要记一个\(trans_{c,x}\)表示在后面加一段长度为\(x\)的\(c\)字符,它的结尾的\(nxt\)会指向哪里。\(link\)同理。
此时就不能暴力往前跳了,而是查最后一段的\(trans\),直接跳过去,然后继承那里的\(trans\)。
不同点在哪呢?你需要统计答案,而且这一段里面每一个字符的\(nxt\)不一定是相同的,所以你要查询前缀和;跳过去之后它后面那一段可能是长度为\(y\)的\(d\)字符,此时\(trans_{d,l}(l\in [1,d])\)都要指向那一段,所以要前缀赋值。
最后你可能还需要开一个主席树维护当前情况每一个位置属于哪一段,就做完了。
代码是不可能写的
LOJ #3056. 「HNOI2019」多边形
手玩可以发现终止状态是所有边都连向\(n\),而最小步数就是没有连向\(n\)的边的个数。
考虑如何求方案数。你发现\(n\)连出去的边会把圆割成若干段,可以把它们视为森林。
然后你发现一段可以被看成是一棵二叉树,于是做完了。
带修改也问题不大,因为只会影响到几个点而已。
LOJ #3057. 「HNOI2019」校园旅行
日常不会做智商题……
暴力很好想:把所有初始合法的点对丢进队列,然后暴力枚举两边往同色点走,\(O(m^2)\)。
然后优化边数??
考虑同色连通块的作用,可以两边在里面乱跳,那么能否跳到同一个点呢?容易发现这和距离奇偶性和是否有奇环有关。对于二分图,只需要留一棵生成树,否则再加一个自环。
异色连通块也差不多,但它肯定是二分图,所以留一棵生成树。
然后边数就变成\(2n\)就可以暴力了。
LOJ #3058. 「HNOI2019」白兔之舞
https://www.cnblogs.com/p-b-p-b/p/11964304.html
我觉得这题比T1可做……
LOJ #3059. 「HNOI2019」序列
寻找性质,发现当\(A_i\ge A_{i+1}\)的时候,必然有\(B_i=B_{i+1}\)。
而且,你发现把\(A_{i},A_{i+1}\)都赋成平均数之后仍然会保证\(B_i=B_{i+1}\),并且答案只会差一个常数,所以可以直接变成平均数。
然后推广一下,一个单调不升子段也是可以直接合并到一起去的。
于是暴力做法就出来了:从左往右维护一个单调栈,每次加一个数的时候就拼命往前合并,直到满足单调不降。当然从右往左合并也是可以的。最后选的\(B_i\)就是单调栈里的数。
如何支持多组询问呢?
大胆猜想可以先把左右的单调栈求出来,然后再合并两个单调栈,答案仍然是对的。不会证明,但很多题都是这么做的。
如何合并两个单调栈?考虑插入一个元素的时候可以二分要合并多少个元素做到\(O(\log n)\),而我们可以先二分右边有多少个要被合并到左边去,然后在左边二分得到真正被合并出了什么,再在右边看是否满足单调不降。
容易发现这是有单调性的。配合线段树上二分就可以做到\(O(n\log^2 n)\)。
两边的单调栈可以预处理出来,左边一边做一边加、右边先做完然后再回退。
我觉得这题比T1T2都可做……HNOI什么毒瘤题目顺序……
HNOI做题记录的更多相关文章
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- project euler做题记录
ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...
- Sam做题记录
Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...
- 退役IV次后做题记录
退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...
- 退役III次后做题记录(扯淡)
退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...
- 退役II次后做题记录
退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...
- BJOI做题记录
BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...
- FJOI2017前做题记录
FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
随机推荐
- c# Windows服务管理
.NET Framework中提供的类库可以很方便的实现对windows服务的安装.卸载.启动.停止.获取运行状态等功能.这些类都在System.ServiceProcess命名空间下. 所以,在开始 ...
- Nginx优化配置,轻松应对高并发
Nginx现在已经是最火的web服务器之一,尤其在静态分离和负载均衡方面,性能十分优越.接下来我们主要看下Nginx在高并发环境下的优化配置,主要是针对 nginx.conf 文件的属性设置.我们打开 ...
- 分布式事务:Saga模式
1 Saga相关概念 1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem发表了一篇Paper Sagas,讲述的是如何处理long lived transac ...
- kaishi
https://zjc.wtc.edu.cn/zs/2019/0623/c2937a54869/page.htm https://zjc.wtc.edu.cn/zs/2019/0614/c593a54 ...
- 【转载】 Windows系统电脑通过设备管理器查看电脑配置信息
在采购电脑或者使用电脑的过程中,有时候我们需要查看到电脑的所有设备硬件信息,此时就可以通过Windows系统自带的设备管理器界面来查看该电脑所有的设备配置信息,包括CPU型号频率.内存.硬盘型号以及容 ...
- Git拉取Gitlab上的代码时,报128的解决方法
今天拉取gitlab上的代码时出现错误,一直返回128 首先我们确定我们在存储库上有没有权限,然后我就去项目中的 Members上看是否有权限,然后发现也是有的. 然后克隆的时候发现输入一万遍密码都还 ...
- Log4j配置详述
/** * log4j基础配置步骤阐述: * 1.引入log4j相关的jar包文件. * 2.创建log4j的配置文件. * 3.测试配置是否成功. */ Log4j 根配置语法 下面引入一 ...
- Odoo定时任务(自动任务)
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826270.html 一:定时任务模型 Odoo中内置了一个定时任务模型 ir.cron ,它定义了一 ...
- 如何在macOS下调整磁盘分区大小?
可以在“macOS”下利用磁盘工具并且不抹掉主分区的情况下,随意更改磁盘分区大小的方法.“OS X”经过几次大版本升级以后,也改名为“macOS”,而且系统自带的“磁盘工具”无论是功能和界面也有很大的 ...
- C语言结构体变量字节对齐问题总结
结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但 ...