1 月日记
Hello 2025!
1.1
跨年夜微信上发了 ≥20≥20 条新年快乐,收到了来自好朋友的红包,金额不多但是心意满满,而且还有她写给我的一封信,我哭死。
早上跟朋友去了趟天府红(专门卖谷子的商场),买了几个名柯的盲袋,意外之喜,出了一个基德的限量款,吧唧新兰一起买的。
晚上返校。
晚自习写了一份学习笔记:二反 & 容斥
心有点累。
「打上花火,往事流转宛若灿烂烟火;忘却过去,唯能忆起君の名字」
1.2
Keep on 容斥 & 二反
P3349 [ZJOI2016] 小星星
学到了新东西:子集反演。
个人领悟感觉和二反有异曲同工之妙,找到博客甩在个人主页了。
其实题目翻译过来就是一个 nn 个结点的无向图(无自环重边)和 nn 个结点的树,对于原本的无向图每个点有编号,树上则没有,问给树上点编号使得其成为一棵原图的生成树的编号方案数。
记用集合 SS 给树编号,且 SS 内每个元素至少用一次的方案数为 fSfS,又记 gSgS 为 SS 内每个元素恰好用一次的方案数(其实本来应该是至多一次,但是抽屉原理得到这里至多和恰好等效)。
最终答案为 f{1,2,…,n}f{1,2,…,n},考虑如何推。
每次我们钦定选择 SS 的子集 TT,我们可以得到:
根据子集反演:
看的出来与二反很类似。
现在考虑如何求 gTgT,记 dpu,x,stdpu,x,st 表示结点 uu 编号为 xx 整树编号状态为 stst 的方案数,枚举状态每次找到在状态中的结点,以下表示为 numinumi,接着树形 dp,这样可以砍掉 dp 数组存状态那一维,以下转移方程:
其中 v∈sonuv∈sonu,eu,veu,v 为表示在原图中是否到达的邻接矩阵,方括号为艾弗森括号。
由此得到:
然后统计答案即可,注意 |T|=popcount(st)|T|=popcount(st)。
P3158 [CQOI2011] 放棋子
考虑由一种棋子放的情况推到 cc 种棋子放的情况。
记 dpi,j,kdpi,j,k 表示前 ii 行 jj 列恰好放完了 kk 种棋子的方案数,这是总的。
记 fi,j,kfi,j,k 表示前 ii 行 jj 列恰好放完 cntkcntk 个 kk 种棋子的方案数,注意到我们定义的是恰好,于是果断记 gi,j,kgi,j,k 表示前 ii 行 jj 列至多放完 cntkcntk 个 kk 种棋子的方案数,这样就可以从二反入手,得到:
二反得到 ff:
每次枚举一个子矩阵进行转移,初始化 dp0,0,0=1dp0,0,0=1:
由于棋子可以每行每列任选放置,统计答案:
P4515 [COCI2009-2010#6] XOR
两个三角形的交的顶点:
腰长:
显然的,对于所有三角形的交,这样算定会算重,考虑容斥,由于此处容斥的集合是三角形面积,容斥系数为 (−2)(−2)。
注意到 N≤10N≤10,考虑状压,容斥系数为 (−2)popcount(st)−1(−2)popcount(st)−1,答案即为:
其中 S∩S∩ 表示状态 ii 三角形交的面积大小。
体育课和班上同学分队踢了 40min,发现前场只有我和另一位俩进攻,最后也是累到躺草皮上,今天没状态也是绝佳机会头球没顶到、凌空无人防守打飞(
哎我真服了我在干嘛。
没吃晚饭饿到爆炸,洗洗睡了。
可恶小保底歪莫娜了我还得攒着抽茜特菈莉,住校生尝试上半攒出 30 抽来(
1.3
上午 %你赛 0+0+20+10=300+0+20+10=30
哎不是我赛时在干嘛,赛后 T1,T2 轻松补出来,怎么会没想到呢。
T1
赛时以为又是数位 dp,发现不可做,开始想高精 + 贪心(a,b≤103a,b≤103)。
显然的一个结论,从大到小取数一定是最优的。
考虑如何具体操作,为了使乘积最大,我们需要将待填的数字 numnum 放到已填数 a′,b′a′,b′ 更小的后面,一开始先从大到小间隔着填到 a′,b′a′,b′ 中,默认 b>ab>a,a′a′ 填完后面全分给 b′b′。
对于第一个 a′i>b′ia′i>b′i,我们不对其进行交换,这是为了保证乘积最大(保证最高位得最大),对于之后的 a′i>b′ia′i>b′i 进行交换,所有操作进行完了再高精乘即可,WA 了两发都是换行打错了。
T2
N≤5×105N≤5×105
显然的,Alice 作为先手的情况下会操作 ⌈n2⌉⌈n2⌉ 次,由于 Alice 只能拿连续的一段区间,即她的总分为连续的一段区间和,由于 Bob 也采用最优策略,他一定有办法限制 Alice 的得分最小,即 Alice 的得分为区间长度为 ⌈n2⌉⌈n2⌉ 的和所有最小值中的最大值,写出了全场最劣解:线段树,常数太大导致的。
破环成链,维护区间和的最小值,再询问区间取最大值。
哎我赛时怎么唐完了(太困了)。
T4
屎山分块,哎我真服了。
分块处理大环,暴力处理小环,每次 22 操作等同于给 11 操作加偏移量,代码屎山,我【数据删除】的调了好久,极度诠释了:“差之毫厘谬以千里”。
P6846 [CEOI2019] Amusement Park
看到 n≤18n≤18 首先想到状压。
记 dpstdpst 表示当前给无向图定向后 DAG 的状态,对于经过 kk 次定向后的 DAG,只需要 m−km−k 次定向即可变成反图,我们恰需要 m2m2 次,故答案为 dp2n−1×m2dp2n−1×m2,现在考虑怎么推 dp。
对于当前状态 stst,理解为当前的边集为 SS,给 SS 定向后全图为 DAG 的方案数,枚举子集 TT,容易发现会有算重的情况,在枚举子集时会存在 T1⊆T2T1⊆T2 的情况,需要容斥,得到 dp 方程:
对 OI 的热爱大不如以前了,【数据删除】,为什么还要硬着头皮学呢? ——【数据删除】
1.4
得知寒假能放整整 17 天,开心极了(
但是年前的安排成功卡掉世界线漫展,差评。
P3160 [CQOI2012] 局部极小值
注意到 n≤4,m≤7n≤4,m≤7,考虑状压。
对于无解情况,只需要判局部最小值周围是否有其他的局部最小值。
记 dpi,stdpi,st 表示已经确定了 ii 个局部最小值,总状态为 stst 的答案,dfs 遍历,每次找出满足条件的局部最小值点数 cntcnt,答案显然为所有状态之和,有转移:
对于当前确定了 ii 个局部最小值,若枚举状态中确定的局部最小值个数 ss 比 ii 大,并不会产生贡献。
对于不是局部最小值的地方,记 sizsiz 表示可以使用的数的个数,有转移:
最终结果 dpn×m,2cnt−1dpn×m,2cnt−1,但是,过程中会出现 sti⊆stjsti⊆stj 的情况,需要考虑容斥,对于 dp 所求的定义转化一下:fifi 表示至少包含 ii 个局部最小值点的方案,gigi 表示恰好包含 ii 个局部最小值点的方案,对于需要满足的点集 SS:
dfs 遍历完所有行之后每次统计答案即可。
P1715 [USACO16DEC] Lots of Triangles P
记区域点数为 cntxcntx,cnt△ABC=cntBlue+cntRed−cntGreen+cntlcnt△ABC=cntBlue+cntRed−cntGreen+cntl,其中 cntlcntl 指在 ll 上且在三角形内的点。
其实就可以看作 lABlAB 下方点数 ++ lBClBC 下方点数 - lAClAC 下方点数,然后实现就显然了,但是存在 lAClAC 在 lAB,lBClAB,lBC 上方的情况,判一下。
[AGC005D] ~K Perm Counting
正难则反,考虑有多少 |pi−i|=k|pi−i|=k 的方案。
记 fsfs 表示至少 ss 个满足 |pi−i|=k|pi−i|=k 的 ii,gsgs 表示恰好 ss 个满足的 ii,二反:
考虑求 fifi,既然要满足要求,pipi 和 ii 一定满足一个二分图:
对于每一条链,只要链顶不连边,一定满足条件。
记 dpi,j,0/1dpi,j,0/1 表示当前第 ii 个点,连了 jj 条边,i,i−1i,i−1 之间是否连边的方案数。
如果不是链顶:
最后得到 fi=dp2n,i,0+dp2n,1,1fi=dp2n,i,0+dp2n,1,1。
答案 n∑i=0gin∑i=0gi。
[AGC040C] Neither AB nor BA
对于奇数位置的字符,有且仅有可能它被偶数位的字符连带删去,翻转奇数位的 A 或 B,变成了讨论不删 AA,BB 合法字符串的数量,对于 A,B 哪一个的字符数量大于 n2,其必是固定的,考虑总方案减去除去大于 n2 的方案,总方案 3n 显然。
枚举大于 n2 的个数,方案数 n∑i=n2+12n−i(n−i)!,意为对于 i>n2,剩余 n−i 随意排列任意选取另外两个字符的方案数,最后答案 3n−n∑i=n2+12n−i(n−i)!。
[ARC100E] Or Plus Max
高维前缀和板。
用 pair 维护最大值和次大值,因为若 xory=K,答案就为前缀最大值,因此转化为 xory⊂K,即维护子集最大次大,高维前缀和统计一下。
1.5
平平无奇的周末。
晚上返校,来的在车上反思了很多。
反思了最近待人处事的一些不对,以及一些学习上的问题。
最近的几个月一直都一心求成,准确来说,一直以来都是这样,总是希望自己在短时间内能够提升水平,在短时间内学懂新知,在短时间内做出一道题,显然,这样的心态最终只会让结果单调不增,我之前有意识到这个问题,但是当时的我并没有放过多心思在这个问题上。
需要做出改变。
机房的大家都开始稳步提升,我仿佛还停留在过去,周围带来的压力也更大,但是俗话说得好:适当的压力可以使人进步。
调整心态是最重要的,或者说是调整学习方法,亦或者说是调整节奏。
不会做的题,自己为什么不去想然后尝试一下呢?不尝试永远不知道结果怎样。
担心的事也很多。
每天除了担心鸡毛蒜皮的小事,更多的,我感到更焦虑的是未来。
自己现在的杂鱼一样的 OI 水平,很难说能在明年拿 NOIP 一等,更别说能冲省队,但是,人们往往站在当下这个角度去描述未来,自然的,谁都想不到未来的自己会是怎么样的(预言家被刀了),上半程一路风顺,下半程说不定是狂风暴雨的洗礼,yishu2 有句话说的很好:“我不在乎你们的结果怎样,但是过程是很重要的。”努力之后的结果是什么,在当下担心毫无所谓。
从当下开始做出改变。
请不要相信,胜利就像山坡上的蒲公英一样唾手可得,但是请相信,世上总有一些美好,值得我们全力以赴,哪怕粉身碎骨。 —— 贺伟
1.6
自行补了 hello 2025 前四题。
E 听 Jmr 讲了,总之就是转成 0/1 边权二分是否小于等于 k,总之乱霍霍一通也是过了。
CF1208F Bits And Pieces
题意中的式子转化成:
首先贪心的,从高到低枚举每一位,首先需要明白的是,在保证答案最大的情况下,能选更小的 i 和更大的 j,k 就一定选。
所以说我们只需要求对于当前枚举的集合的超集中是否有两个比 i 大的下标即可,高位前缀和维护最大值次大值即可。
和高中的同学们踢球已经不止一个人问我要不要加它们球队踢我们学校联赛了 (?
1.7
上午 %你赛,成功暴零喜提全场最低。
喵的我要自闭了。
T1
喵它宝贝的赛时想的 DP 成功挂掉,如果要实现能过还它宝贝的是全场最劣解。
喵它宝贝的竟然是 2-SAT。
对于 x,y 列 1 的个数:
-
如果 1 的个数和 >2,无解。
-
如果 1 的个数和 <2,那它宝贝的是绝对有解的。
-
如果 1 的个数和 =2,就需要它宝贝的分讨了。
- 如果两个 1 在同一列,则它宝贝的 1 所在的两行必须翻转一个。
- 如果一列一个,要它宝贝的两行都翻转,要么都不。
然后就可以他宝贝的并查集维护了,对于 1 情况合并 (x,y+n),(x+n,y),对于 2 情况合并 (x,y),(x+n,y+n),然后它宝贝的再判一下 (x,x+n) 是否在同一连通块,如果是就无解,最后答案就它宝贝的比较显然了:2cnt2,其中 cnt 为连通块个数。
T2
首先:ai+1−ai=1→ai+1−(i+1)=ai−i,转化成使区间内所数相等。
喵它宝贝的这第一步转化赛时根本没想到,这辈子有了。
显然只需要将区间的数全部变成中位数一定是最它宝贝的优的,用两个 multiset 维护动态窗口内大于中位数和小于中位数的数,分别记它们为 s1, s2。
对于中位数的查询:
- 窗口大小为偶,中位数为 s1.rbegin()+s2.begin()2。
- 否则,中位数为 s2.begin()。
对于数的插入:
- 如果 s1,s2 均为空,则插入到 s2。
- 否则判断是否 ≥s2.begin(),如果是则插入到 s2,否则插入到 s1。
为使中位数符合预期,s1,s2 的大小差应 ≤1,需要对 s1,s2 进行一个平衡操作。
- 如果 s2 中的元素多于 s1 的个数 +1,将 s2.begin() 插入 s1。
- 否则如果 s1 元素多于 s2,,将 s1.rbegin() 插入 s2。
最后记 suma,sumb 分别为 s1,s2 内的和,mid 为中位数,答案即为 s1.size()×mid−suma+sumb−s2.size()×mid。
喵它宝贝的。
T3
喵它宝贝的。
无奖竞猜:今天日记中有多少个喵,多少个宝贝的?
21:20 下班!艹!
1.8
斜率优化,启动!
一看专题抓的题,全紫,第一反应是我做鸡毛啊。
果断先补容斥剩的两道题。
P6551 [COCI2010-2011#2] CRNI
O(n6) 不用说。
O(n4) 枚举两个不相交的黑色子矩阵。
考虑如何结合容斥计算(搬题解的一张图):
在大的黑色矩阵中剔除一个小的黑色矩阵(红框),最终的答案贡献即为上下左右的黑色矩阵的贡献减去四个角(蓝框)的贡献。
所以问题成功转化为求一个大的黑色矩阵中所有黑色子矩阵的贡献和,我们可以二位前缀和预处理然后转化成以 (i,j) 为右上角的矩阵的贡献,单调栈可以维护,复杂度 O(n2)。
瓶颈在于我们枚举矩形的 O(n4),首先想到预处理给优化掉,其实需要进行枚举的就是 2 种矩阵,边相接和角相接的矩阵,预处理就能将总复杂度优化成 O(n2)。
[AGC039C] Division by Two with Something
Orz.
P2365 任务安排(最弱版)
P10979 任务安排 (中档)
P5785 [SDOI2012] 任务安排(最强版)
三者放一起是有原因的,个人评价三者算是斜率优化 dp 入门三件套,故写题解:click。
P3195 [HNOI2008] 玩具装箱
见 oiwiki
P2120 [ZJOI2007] 仓库建设
很有意思的一道题。
显然对于货物移动的代价为 pi×xi,记 dpi 表示在 i 建工厂使得前 i 均不被淹没的最小花费,转移柿子:
令 si=i∑k=1xk×pk,p 做前缀和并拆掉 min(故技重施):
不妨设 a,b 两决策点,且 b 优于 a:
故斜率优化,决策点集 (pi,dpi+si),pi,si 单调递增,做法为 O(n),只需要判 pi=pi−1 的情况,若此时 y>0 视作正无穷,反之 y<0 视作负无穷,y=0 就为 0。
如果真正理解了并能够成功列出转移柿子,就可以快速的进行一个柿子的推和转化,斜率优化挺有意思哈。
1.9
上午 %你赛,暴零。
不想说了啊啊啊啊啊啊啊啊啊啊啊。
T1
神经题,赛时全想到了,实现大锅锅锅锅锅锅锅锅锅锅锅锅。
T2
赛时磕 T1 去了,没多想这题,赛后很快想到。
T4 CF1031F Familiar Operations
食我烫烫烫烫烫烫烫天天天天天天天天天天天天天天天天天。
一个下午成功把自己从想跳的边缘拉了回来。
但是怎么变颠了(?
P3628 [APIO2010] 特别行动队
记 dpi 表示以 i 结尾的特别行动队的最大战斗力和,枚举拆分点 j,记 si 为 xi 的前缀和,得到转移柿子:
拆拆拆拆拆拆拆拆柿柿柿柿柿柿柿柿子子子子子子子子:
令:
得到:
故斜率优化,因为 ki 单增,故采用单调队列 O(n) 维护最左侧最优决策点和下凸包。
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
21:20 下班回寝!阿米诺斯!
1.10
调超李吗线段树和 cdq 太久了忘写了(
cdq 怎么这么难我草。
啊啊啊啊啊啊啊啊啊啊啊
1.11
P4655 [CEOI2017] Building Bridges
记 dpi 表示前 i 根柱子连接的最小代价,记 sumwi 为 wi 前缀和,得到转移:
拆拆拆拆拆拆拆拆柿柿柿柿柿柿柿柿子子子子子子子子:
min 里面的可以超李吗线段树维护。
P4072 [SDOI2016] 征途
记 dpi,j 表示前 j 天走 i 段路的最小答案。
首先,我们需要知道答案式子,记总路程为 S,记 di 为每段路的长度,答案:
只需要维护 (m∑i=1di)2 的最小值就行,所以 dp 方程:
拆拆拆拆拆拆拆拆柿柿柿柿柿柿柿柿子子子子子子子子
设决策点 k 优于 l:
然后就斜率优化,分子看做 y,分母看做 x,注意每次从 j−1 转移。
明天 %你赛考 NOIP,不柿戈门(
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
1.12
上午嗯哦挨批 %你赛,成功挨批(Totalpts=0)。
不是戈门 T1 暴力打挂了?戈门 T2 原题不知道?
六百六十六。
T1
O(nlogn) 可以是 Segmentree 草过去。
记 matchi 为与 i 匹配的括号,ai 表示从 i 开始往后有多少个合法段,bi 表示从 i 开始往前有多少个合法段,ini 表示包含 (i,matchi) 的左括号的下标。
记 Ansi 为 i 对应的答案:
用栈维护求 matchi 遇到右括号弹出栈顶并更新 matchi。
T2
T3
记 fi,j 表示切到 (i,j) 处对应的方案数,不去重的状态下,有转移:
但是我们要去重,注意到对于一行中连续的一段数字,任意删除一个最终结果不会改变,都是同一个结果,记 gi,j 表示切到 (i,j) 处与 (i,j−1) 处相同的数量,连续的不相等的并不会产生贡献,考虑相等的情况,其有贡献的区间为 [j−k,j+k−1],得到柿子:
然后前缀和优化即可。
六百六十六全是桂。
CF311B
记 dpi,j 表示前 i 个饲养员带走前 j 只喵喵的最小等待时间,记 timi 表示对于喵喵 i 的最小等待时间,sumi 为 timi 前缀和:
设决决决决决决策策策策策策点点点点点点 x,y 且 x 优于 y:
斜斜斜斜率率率率优优优优化化化化即即即即可可可可。
写了一份 斜率优化 dp 【学习笔记】。
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
(每日名言回归了)
大御所大人,是在诉说什么心事吗。 ———— 神里绫华
1.13
上午 vp 昨晚 Cf 996 Round。
脑袋比较清醒。
A Two Frogs
最优策略一定是 Alice 和 Bob 相向跳,故与它们之间距离的奇偶性有关,不难发现若为偶数 Alice 必胜,反之 Bob 必胜。
B Crafting
统计出 ai≥bi 时最小的 ai−bi,这是最小需要的 −1 操作次数,ai<bi 时统计 bi−ai 的和,同时记录次数,即为需要 +1 操作多少次和总的差值。
在不需要 +1 操作或者仅有一次且总差值比 −1 最小操作次数小则有解。
C The Trail
思路在代码注释里。
#include <bits/stdc++.h>
#define int long long
#define getchar() _getchar_nolock()
#define mkp make_pair
using namespace std;
inline int readint() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit (ch)) f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit (ch)) res = (res << 1) + (res << 3) + (ch ^ 48), ch = getchar();
return res * f;
}
inline string readstr() {
string sh = "";
char ch = getchar();
while (ch == '\n' || ch == ' ' || ch == '\r') ch = getchar();
while (ch != '\n' && ch != ' ' && ch != '\r') sh += ch, ch = getchar();
return sh;
}
const int MAXN = 2e3 + 10;
int T, n, m, mat[MAXN][MAXN], sumr[MAXN], sumc[MAXN];
set <int> sr[MAXN], sc[MAXN];
queue < pair<int, int> > q;
string str;
inline void init() {
sr -> clear(), sc -> clear();
while (!q.empty()) q.pop();
}
signed main() {
T = readint();
while (T --) {
/* 目标行和为 x,当前和为 sum,故当前 a[x][y] = x - sum */
/* 目标列和为 x',当前和为 sum',故当前 a[x][y] = (x' - sum') - (x - sum) */
/* 当前行 / 列需要填的点有 cnt 个, a[x][y] = (1 - cnt) * x - sum,x 赋为 0 即可,然后 a[x][y] 就取当前行 / 列和的相反数 */
/* What Can I Say. */
init();
n = readint(), m = readint(), str = readstr();
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
mat[i][j] = readint();
sumr[i] += mat[i][j], sumc[j] += mat[i][j];
}
}
sr[1].insert (1), sc[1].insert (1);
int x = 1, y = 1;
for (int i = 0; i < str.size(); i ++) {
if (str[i] == 'D') x ++;
else y ++;
sr[x].insert (y), sc[y].insert (x);
}
/* 插入需要走的点 */
for (int i = 1; i <= n; i ++) {
if (sr[i].size() == 1) q.push (mkp (i, -1)); /* 只需要走一个方向的 */
}
for (int i = 1; i <= m; i ++) {
if (sc[i].size() == 1) q.push (mkp (-1, i)); /* 只需要走一个方向的 */
}
/* 保证最优 */
while (!q.empty()) {
auto [u, v] = q.front(); /* AUV */
q.pop();
if (u == -1) { /* 修改列 */
if (!sc[v].size()) continue; /* 没有不管 */
u = *sc[v].begin();
mat[u][v] = -sumc[v]; /* 直接将列和变成 0 */
sumr[u] += mat[u][v], sumc[v] += mat[u][v]; /* 更新行和列和 */
sr[u].erase (v), sc[v].erase (u); /* 删除可爱的元素 */
if (sr[u].size() == 1)
q.push (mkp (u, -1));
if (sc[v].size() == 1)
q.push (mkp (-1, v));
}
else { /* 同理啊显然的 */
if (!sr[u].size()) continue;
v = *sr[u].begin();
mat[u][v] = -sumr[u];
sumr[u] += mat[u][v], sumc[v] += mat[u][v];
sr[u].erase (v), sc[v].erase (u);
if (sr[u].size() == 1)
q.push (mkp (u, -1));
if (sc[v].size() == 1)
q.push (mkp (-1, v));
}
}
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++)
printf ("%lld%c", mat[i][j], " \n"[j == m]);
} /* Genshin Impact, Launch! */
}
/* 茜特菈莉小姐可爱捏 */
return 0;
}
P5308 [COCI2018-2019#4] Akvizna
新东西:wqs 二分
记 dpi,j 表示前 j 轮干掉 i 个选手最多可获奖金。
显然的一次函数:
故斜率优化,可是它优化完还是【数据删除】的 O(n2),于是乎 wqs 二分,就变成 O(nlogV)。
P6302 [NOI2019] 回家路线 加强版
记 dpi 乘坐完前 i 班列车最小的烦躁值。
很像一次函数,故:
故斜率优化,下凸壳且不断向右加点。
瓶颈在于将条件 (xj=yi)⊕(qj≤pi) 加入,对于 xj=yi,对每个点开单调队列查询,对于 qj≤pi,对输入按照 p 排序,枚举时间知道枚举到当前 p 再插入新的点,这样就是 O(maxqlogm)
P4027 [NOI2007] 货币兑换
记 xi 为第 i 天 A 卷数,为第 i 天 B 卷数,fi 为第 i 天操作结束所得最大金钱数目。
fi 在第 i 天不买入:fi=max{fi,fi−1}
买入:
请李超上树即可。
AT_dp_z
斜率优化板子,注意青蛙是从 1 开始跳的。
啊啊啊啊啊踢球脚抽筋了现在还没好。
1.17 - 1.22 上课成功卡掉世界线 1.18 - 1.21。
从今以后,我会一直与你同行。直到所有星辰消隐,直到所有的火熄灭,直到迷烟散尽。 —— 茜特菈莉
1.14
今天是 @alpharchmage 的生日,祝 Ta 生日快乐!
去了几个人去清北冬令营,但是机房还是 10+ 入,非常热闹。
上午 %你赛,20+0+20+0=40 砍下全场 rank -> end()。
赛后发现 T1,T2 放反,T2 是唐题但赛时太困没看,唉唉。
T1 [ABC136F] Enclosed Points
为什么 T1 是紫啊喂
显然的 O(n2n) 可以暴力。
T2 [ARC071E] TrBBnsformBBtion
最终会发现会陷入全部变为 A 的循环,将 A 换成 1,B 换成 2,最后只需要看 [l,r] 的和两串是否同余 3 即可。
T3 P9640 [SNCPC2019] Digit Mode
T4 [ARC070E] NarrowRectangles
终于可以安安心心去学左偏树了。
不对我 T3 还没补(
啊啊啊啊啊
1.15
正式开左偏树专题。
在捣鼓一篇文章约 20min 后开始敲板子。
P3377 【模板】左偏树/可并堆
板。
P2713 罗马游戏
板。
P1456 Monkey King
板?(大根堆建成小根堆故没过样例)
P1552 [APIO2012] 派遣
最终的答案:max{Lu×cntu},其中 cntu 为从以 u 为根的子树中选出的 cntu 个节点。
故选择建大根堆维护薪水,一开始,若自己满足条件故选择派自己,否则不选自己遍历子树,在从叶子结点向上推的过程中,每次合并根和儿子,若选择节点的薪水和大于 m,减去堆中最大的直到 ≤m。
P3648 [APIO2014] 序列分割
不是说好的做左偏树的呢,水一道斜率优化应该没事吧。
记 dpi,j 表示前 i 个数划分 j 次的最大得分,sumi 为前缀和:
令 dpi,j 为 fi,dpk,j−1 为 gk。
设决策点 x 优于 y:
故斜率优化,维护下凸壳。
咕咕咕。
P2900 [USACO08MAR] Land Acquisition G
注意到一个关键性质:假如我们钦定宽递减,最终购买的土地的长是递增的,且每一组土地在排序后是连续的。
故排序预处理,重新洗牌数组使得宽递减。
记 dpi 表示前 i 块土地的最小费用,思路即为固定 li 枚举 w,因此得到:
设决策点 x 优于 y:
瓶颈竟然在排序(?
1.17
寒假集训,启动!
P3261 [JLOI2015] 城池攻占
思路在代码里,这题是看的文章里讲的例题。
P4331 [BalticOI 2004] Sequence 数字序列
论文例题 Solution
代码中有思路 Submission
P6242 【模板】线段树 3(区间最值操作、区间历史最值)
拼尽全力终于战胜。
上午 %你赛,题目:https://www.cnblogs.com/cztq/p/17561394.html
被创飞了(
终榜 30+10+10+0=50pts
T1
可是 T1 确实唐,我也唐。
打标找规律即可,发现一堆 1 聚在一起,只有一个 1 在 0 之间。
T2 & T4
并未改错。
T3
P10639 BZOJ4695 最佳女选手
一遍过,爽!
代码总长 8 Kb。
分别维护最大值标记、最小值标记、加法标记,每次一起下传标记即可,更新加法标记的同时更新最大最小值标记、最大最小值、次大次小值。
在更新最大值标记时,如果遇到既是次大值又是最小值需要特判,更新最小值标记同理。
喵的手都要废掉了。
所幸 CDFLS 让我们拥有 17days 寒假。
1.18
吉司机线段树专题, 码量 += inf。
一口气开了三个 DS 专题 (?
会死人的啊喂
上午 vp 昨天 CF2056
A
唐。
B
对于两点 (i,j),其对应值为 (x,y):
反推然后排序。
C
手玩数据偶然发现把 1,2 放最后前面放 1 n−2 最优,样例叉掉我们结论故果断输出样例。
E
对于一棵 n 个节点的二叉树,共有 Catelann 种形态。
线段最优是一个覆盖两个,转换为求 n−1 个节点构成二叉树的形态。
相当于每次限制第 i 条线段,分别考虑子树、兄弟、父亲,用栈维护。
元旦老人与数列 (UOJ)
P6242 稍微变了一下,维护的东西还是一样的。
CTSN loves segment tree
我们将需要查询的 Ai,Bi 分类:
-
Ai,Bi 均为待查询 [l,r] 内最大值。
-
Ai 为待查询 [l,r] 最大值,Bi 为非最大值。
-
Ai 为待查询 [l,r] 非最大值,Bi 为最大值。
-
Ai,Bi 均为待查询 [l,r] 非最大值。
对此,我们分别计其为 cVal1,1,cVal1,0,cVal0,1,cVal0,0。
在下放最小值、加法标记时跟模板一样,对于 A 数组的标记下放会影响 cVal1,1,cVal1,0,对于 B 数组的标记下放会影响 cVal1,1,cVal0,1,加法标记下放时 cVal1,1,cVal1,0,cVal0,1,cVal0,0 均会被影响,考虑如何维护。
在从左右儿子节点更新了根节点的最大值后,我们分 4+4 类讨论。
以下根节点记为 rt。
对于左儿子,记为 lson:
-
lson A 中的最大值、B 中的最大值和 rt 相等,不会有影响,直接更新 cVal1,1,cVal1,0,cVal0,1,cVal0,0。
-
lson A 中最大值与 rt 相等,B 中最大值不相等,故 cVal1,0,cVal1,1 不存在,赋为 −inf,更新 cVal0,0,cVal0,1。
-
lson B 中最大值与 rt 相等,A 中最大值不相等,故 cVal0,1,cVal1,1 不存在,赋为 −inf,更新 cVal1,0,cVal0,0。
-
lson A 中最大值、B 中最大值与 rt 均不相等,故 cVal0,1,cVal1,0,cVal1,1 均不存在,赋为 −inf,更新 cVal0,0
对于右儿子,同理做,只需要每次取 max。
区间查询的最终结果即为四种情况的最大值:
总复杂度 O(mlog2n)。
说句闲话:敲代码花了我 1h34min,码量 7.5Kb。
码量真滴大。
1.19
今天真的很不走运,唉唉。
上午 %你赛,00000。
看来需要的是转换学习策略,以及调整心态,可以试试玩原神调整一下
总之,不能再这样颓丧下去了,尽快做出改变。
All in all,做题一定要笑 😃
T1 Gym - 101915I
正着排序一次,记下序号,字符串翻转再排一次,将现在的序号插入树状数组,我们会得到,已经在树状数组中的数据,一定是第二次排序后小于当前字符串序号的,树状数组中小于第一次排序序号的数据,一定是第一次排序小于当前字符串序号的,故维护两个树状数组,分别维护以含 m 字符串结尾的最长字符串序列和不含 m 字符串序列的长度。
T2 Gym - 102803E
对于给定的 SA 数组,我们考虑记录字符串 rankSAi=i,分情况讨论:
-
∀i∈[2,n] and SAi=−1,则有 SSAi−1≤SSAi→rankSAi−1>rankSAi,故有 SSAi−1<SSAi。
-
∀i∈[2,n] and SAi≠−1,考虑 0≤j<heighti,则有 SSAi−1+j=SSAi+j,若 SAi−1+heighti≤n,还有 SSAi−1+heighti<SSAi+heighti。
考虑差分约束或拓扑,选择拓扑。
发现 ∀i∈[1,n],SAi 就是一个很好的拓扑序,并且这样操作过后答案满足字典序最小。
故将小于关系连边存在 largei 中,等于关系并查集维护,初始时 SSA1=a。
每次 SSAi=max{SSAi−1,SSAj(j∈largei)+1},然后更新 ∀j∈[1,i−1] 中跟 SAi 有等于关系的。
T3 P7054 [NWRRC2015] Graph
想要最小的拓扑序?将队列改成小根堆即可。
考虑如何得到最小拓扑序最大,贪心的思考,对于即将加入拓扑的最小编号的点,我们肯定不想让其加入,故给它增加一条入边,那么这条入边从哪里来呢?其实从其拓扑序的上一个来即可。用大根堆存储这样需要删除的点即可做到最小拓扑序最大。
具体流程,以下删除操作新定义为插入答案拓扑序后对出边的点进行拓扑排序,对于打标记的点记录连边,插入操作新定义为给 K 减一后打标记插入大根堆:
-
所有入度为 0 的点放到小根堆中。
-
分情况讨论:
- 小根堆大小为 0,删除大根堆堆顶。
- 小根堆大小为 1 且 K>0,且大根堆堆顶大于小根堆堆顶,插入小根堆堆顶;否则删除小根堆堆顶。
- 小根堆大小 >1 且 K>0,插入小根堆堆顶;否则删除小根堆堆顶。
- 输出答案。
T4 P4737 [CERC2017] Buffalo Barricades
使我大脑旋转,十分巧妙的一道题。
如图:
对于本身的一个 (x′i,y′i),我们只需要求其所围方框内的点 (xi,yi),也就是说对于每一个 (xi,yi),我们需要维护离它最近的 (x′i,y′i) 且满足 x′i>xi,这个可以用 set 实现,将 (xi,yi),(x′i,y′i) 都按照 y 排序。
但是,观察这张图我们会发现,划出的方框存在包含和冲突的关系。
如图,对于 B,D,先假设 C 不存在,故 D 包含 B,A 包含 D,所以说 A 最后的结果就是 D 的答案加上 A 的答案,对于我来说不显然的,这是一个树形结构,也就是说我们记录父亲指针。
(x′i,y′i) 加入的先后关系也会有影响,上一段讨论 D 包含 B,若 B 在 D 之前进入,B 的答案就不能累加到 D 的答案上,反之,若 D 在 B 之前进入,就可以,故我们需要维护进入的时间关系,即为儿子节点只有在父亲节点加入之后才能对父亲产生贡献,使用并查集路径压缩,从下往上进行维护。
最后就是如何求 (x′i,y′i) 不被儿子节点覆盖的点对,正如方才排序时,我们需要同时按时间为第二关键字从大到小排序,因为对于 (xi,yi),如果 (x′j,y′j) 和 (x′k,y′k) 同时覆盖它,但是 (x′j,y′j) 先进入,固然我们将 (xi,yi) 算作被 (x′j,y′j) 覆盖。
答案统计就是合并连通块的时候统计,类似于带权并查集。
做题一定要笑 😃
1.20
上午 vp CF 998 Round
A
唐。
B
p 排列每一列的数 mzi,pi 必须递增,乱搞一通过掉。
C
Bob 一定会选 a 和 k−a,维护贡献即可。
D
A1>A2 肯定不行,A1−A2>A3 也不行,以此类推判断即可。
E
思路在代码里。
后面赛后补得。
F
对于 ai,其实其中大部分都是 1,不是 1 的只有不到 20 个。
考虑 ∏ai=n,记 dpn,x 表示满足条件的方案数,故有:
表示最后填它某一个因数。
记 f(n,l) 表示填长为 l 的 1,乘积为 n 的方案:f(n,l)=l∑d=1(ld)dpn,d
枚举填 1:L∑l=1l∑d=1(ld)dpn,d=L∑l=1(L+1l+1)dpn,l。
这就是答案。
G
P4314 CPU 监控
分别维护区间加标记,区间加阶段标记,区间最大值,区间次大值,区间推平标记,区间推平阶段标记。
【清华集训2015】V
维护最大值加法标记,历史最大值加法标记,再维护两个取 max 的标记。
困困困困困困困困困困困困
做题一定要笑 😃
1.21
寒假倒计时 1.5day
上午 vp CF 999 Round
见证 jiangly 上 Tourist!
A
如果有偶数存在,答案就是奇数个数 +1,若没有就是奇数个数 −1。
B
找到最小的相同的数对,然后找到满足 |a−b|<2c 的即可,c 是腰长 a,b 是底。
C
记 dpi,0/1 表示第 i 个人是诚实 / 说谎人的方案数。
-
第 i 个人是说谎者,i−1 必定为诚实,所以有 ai−1+1 个骗子。
-
第 i 个人是诚实,所以有 ai 个说谎者。
转移方程:
答案即为 dpn,0+dpn,1。
D
a,b 集合的和不同,一定无解。
操作可以转换成选择相同或相差 1 的两个数,将其修改成它们的和,即两个数转化成一个数。
对于 a 中的最大值 aposa 和 b 中的最大值 bposb:
-
如果说 aposa>bposb,无解。
-
如果说 aposa=bposb,没有影响。
-
如果说 aposa<bposb,则 bposb 一定是 ⌊aposa2⌋+⌈aposa2⌉ 合成的。
用 multiset 维护这样的操作即可。
本文作者:_Tomori
本文链接:https://www.cnblogs.com/Tomori0505/p/18646163
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】