QOJ 5458. Shortest Path Query QOJ 5458. Shortest Path Query
首先想到每次询问在 DAG DAG 上 d p d p 一次求最短路
这是没法优化的
考虑预处理到 i i 可能经过的黑白边数
即预处理 f i , j f i , j 表示经过 j j 条黑边到 i i 所需经过的最少白边数量
可以视为点对 ( j , f j ) ( j , f j )
那么询问就是找到一个点 ( x , y ) ( x , y ) 使 a x + b y a x + b y 最小
这个是很好做的,维护下凸包,询问在凸包上二分即可
而观察一开始的 d p d p 转移,发现只转移下凸包上的点就足够了,不在凸包上的点不优,转移出去也不优
这个复杂度是怎样的呢?题解中说对于一个 i i ,它至多有 O ( n 2 3 ) O ( n 2 3 ) 个状态在凸包上,即凸包上点数有保障,那么总复杂度就是 O ( m n 2 3 + q log n 2 3 ) O ( m n 2 3 + q log n 2 3 )
提交记录
[CF1634F] Fibonacci Additions [CF1634F] Fibonacci Additions
判断两数组是否相等可以对应位相减,判断是否全为 0 0 即可
考虑怎样描述一次区间操作,可以快速判断是否全为 0 0 ?
区间加斐波那契数列不好用数据结构打标记,另寻它路
注意到斐波那契数列有很好的递推形式,其差分 D i = f i − f i − 1 − f i − 2 D i = f i − f i − 1 − f i − 2 后为 f 1 , f 2 − f 1 , 0 , 0 , . . . f 1 , f 2 − f 1 , 0 , 0 , . . .
如果 A , B A , B 的差数组也如此差分,那么照 s i = D i + s i − 1 + s i − 2 s i = D i + s i − 1 + s i − 2 这样做前缀和后便可复原
此时不难发现区间加斐波那契数列就变成 D l ← D l + f 1 , D r + 1 ← D r + 1 − f r − l + 2 , D r + 2 ← D r + 2 − f r − l + 1 D l ← D l + f 1 , D r + 1 ← D r + 1 − f r − l + 2 , D r + 2 ← D r + 2 − f r − l + 1
O ( 1 ) O ( 1 ) 修改,记录 0 0 的数量即可判相等
似乎许多 m m 阶常系数递推数列都可以这样做 O ( m ) O ( m )
提交记录
[ABC270Ex] add 1 [ABC270Ex] add 1
计数器 i i 均大于等于 A i A i 这个终止条件不好体现,如果每个计数器从 A i A i 开始,+ 1 + 1 边 − 1 − 1 ,那么只需关心最大值是否小于等于 0 0
能否只将最大值纳入 d p d p 状态?这个足够的,考虑最大值 m x m x ,找到 r r 使得 A r < m x ≤ A r + 1 A r < m x ≤ A r + 1
操作 1 1 到 r r ,最大值变为 m x − 1 m x − 1 ;操作 r + 1 r + 1 到 n n ,最大值相应变为 A r + 1 A r + 1 到 A n A n 。也就是只需要最大值就可以更新 d p d p 状态
那么由此写出转移 f k = 1 n ∑ n i = r + 1 f a i + r n f k − 1 , k ∈ ( A r , A r + 1 ] f k = 1 n ∑ i = r + 1 n f a i + r n f k − 1 , k ∈ ( A r , A r + 1 ]
移项,f k − 1 = n r f k − 1 r ∑ n i = r + 1 f a i − n r f k − 1 = n r f k − 1 r ∑ i = r + 1 n f a i − n r
这样就有顺序了,但 f a n f a n 才是要求的呀,只知道 f 0 = 0 f 0 = 0
所以设 f a n = x f a n = x 递推到 f 0 f 0 解出 x x 即可
转移写个矩阵就够了
提交记录
P4062 [Code+#1]Yazid P4062 [Code+#1]Yazid 的新生舞会
发现一种暴力做法 O ( n log 3 n ) O ( n log 3 n ) ,比一些人写的 O ( n log n ) O ( n log n ) 还快(事实上三 log log 能过 5 e 5 5 e 5 已经很震撼了)
数区间不难想到扫描线或者分治
但考察众数较为困难,所以从暴力开始
不难想到暴力枚举区间 O ( n 2 ) O ( n 2 ) ,而如何判断区间是否合法可以 O ( n ) O ( n ) ,因为绝对众数很厉害,枚举区间时顺势扫下,相异两数同时删掉,总复杂度 O ( n 2 ) O ( n 2 )
类似上面相消思想,枚举绝对众数,将其赋为 1 1 ,其余赋为 − 1 − 1 ,区间合法只需区间和为正
于是 O ( n 2 log n ) O ( n 2 log n ) 成功负优化。
如何去掉 n n ?
下面看分治的威力
考虑分治,沿用上述做法,统计跨过 m i d m i d 的区间,做到 O ( n 2 log 2 n ) O ( n 2 log 2 n ) 再度负优化
注意到此时区间要跨过 m i d m i d ,把可能成为众数的数拉出来,也就是只枚举这些有希望的数
而这是 O ( log n ) O ( log n ) 级别!那么就做到了 O ( n log 3 n ) O ( n log 3 n ) ,非常强大的逆袭
重要的是这三个 log log 都是小常数小空间小码量的东西
于是就出现了三 log log 过掉 5 e 5 5 e 5 并打败一些 O ( n log n ) O ( n log n ) 的伟大时刻
提交记录
QOJ 5459. Goose, goose, DUCK? QOJ 5459. Goose, goose, DUCK?
数区间,考虑扫描线,维护有哪些 l l 合法
每次移动 r r ,只会对一种数产生影响,可以确定的不合法 l l 是一段区间,同时之前有一段区间可能变得合法
所以维护每个 l l 到当前 r r 有几种数不合法,只需线段树上维护 + 1 , − 1 + 1 , − 1 的标记,然后数 0 0 的数量
注意到 0 0 一定是最小值,所以是方便维护的
QOJ 5466. Permutation Compression QOJ 5466. Permutation Compression
显然可以贪心地从大到小删要删的数,删的时候选区间也可以贪心的选
那么只要动态维护这个序列,查询某数作为最大值的极大区间的大小
线段树即可
QOJ 5301. Modulo Ruins the Legend QOJ 5301. Modulo Ruins the Legend
题意转化为求 ( a x + b y + c ) mod m ( a x + b y + c ) mod m 的最小值
先考虑这样的问题,求 ( a x + b ) mod m ( a x + b ) mod m 最小值
设 a x + b ≡ k m + r ( mod m ) ⟹ a x + k m ≡ r − b ( mod m ) a x + b ≡ k m + r ( mod m ) ⟹ a x + k m ≡ r − b ( mod m )
有解当且仅当 r ≡ b ( mod gcd ( a , m ) ) r ≡ b ( mod gcd ( a , m ) ) ,得 r m i n = b ( mod gcd ( a , m ) ) r m i n = b ( mod gcd ( a , m ) )
事实上我们有多元一次不定方程的存在性定理
所以原问题答案为 c mod gcd ( a , b , m ) c mod gcd ( a , b , m )
QOJ 5302. Useful Algorithm QOJ 5302. Useful Algorithm
考虑枚举二进制位 x x ,统计 w x ( d i + d j ) m a x w x ( d i + d j ) m a x
两个 d d 可相加需满足 c i mod 2 x + 1 + c j mod 2 x + 1 ≥ 2 x + 1 c i mod 2 x + 1 + c j mod 2 x + 1 ≥ 2 x + 1
令 D v = max { d i | c i = v } D v = max { d i | c i = v } ,D ′ v = max { d i | c i = 2 x + 1 − v } D v ′ = max { d i | c i = 2 x + 1 − v }
那么就是求 max { D i + D ′ j | i ≥ j } max { D i + D j ′ | i ≥ j }
这个可以利用线段树的分治结构,统计当前区间跨过 m i d m i d 的最优点对答案,并记录当前区间所有子区间的最优答案
修改用 multiset
或 priority_queue
维护 D v , D ′ v D v , D v ′ 即可
总复杂度 O ( ( n + q ) m log n ) O ( ( n + q ) m log n )
QOJ 5313. Please Save Pigeland QOJ 5313. Please Save Pigeland
d d 显然取 gcd gcd ,所以 x x 确定时整个式子是确的定,而 x x 也就这 n n 个数中选
考虑求 ∑ d i s ( x , c i ) ∑ d i s ( x , c i ) ,可以换根 d p d p 求出每个 x x 的答案
再考虑 d d 怎么求。需要维护 gcd ( a 1 , . . . , a m ) gcd ( a 1 , . . . , a m )
如果同理应用上面的 d p d p 则需要支持整个式子每个 a a 加上一个数,并且两个 gcd gcd 式子合并
套路的辗转相减有式子 gcd ( a 1 , . . . , a m ) = gcd ( a 1 , a 2 − a 1 , a 3 − a 1 , . . . , a m − a 1 ) gcd ( a 1 , . . . , a m ) = gcd ( a 1 , a 2 − a 1 , a 3 − a 1 , . . . , a m − a 1 )
记 f = a 1 , g = gcd ( a 2 − a 1 , a 3 − a 1 , . . . , a m − a 1 ) f = a 1 , g = gcd ( a 2 − a 1 , a 3 − a 1 , . . . , a m − a 1 )
那么加上一个数 w w 有 ( f , g ) → ( f + w , g ) ( f , g ) → ( f + w , g )
合并两个式子 ( f 1 , g 1 ) , ( f 2 , g 2 ) ( f 1 , g 1 ) , ( f 2 , g 2 ) 有 ( f 1 , gcd ( g 1 , f 2 − f 1 , g 2 + f 2 − f 1 ) ) = ( f 1 , gcd ( g 1 , f 2 − f 1 , g 2 ) ) ( f 1 , gcd ( g 1 , f 2 − f 1 , g 2 + f 2 − f 1 ) ) = ( f 1 , gcd ( g 1 , f 2 − f 1 , g 2 ) )
g 2 + f 2 − f 1 g 2 + f 2 − f 1 是要维护 a i − a 1 a i − a 1 这样的形式,对应加上一个数需要维护的形式
总复杂度就是 O ( n log w ) O ( n log w )
实现了一下,发现还是有点细节的
因为合并操作的不可减,所以维护一个点向上的从关键点出发的所有路径到这个点的 ( f , g ) ( f , g )
注意当前点若为关键点,那本身就有一条长为 0 0 的路径,要记录进来
最重要的是 ( f , g ) ( f , g ) 的维护,注意空路径
标记是否有路径,并且单路径视为 ( d i s , d i s ) ( d i s , d i s ) 维护成 ( d i s , 0 ) ( d i s , 0 ) 表示差的形式
因为偷懒不想开多数组结果判断一个点是否是关键点变成了子树中是否有关键点,改了上千年,怎么都没发现
最后交了 11 11 发终于 AC
了,太难了啊
提交记录
QOJ 5307. Subgraph Isomorphism QOJ 5307. Subgraph Isomorphism
简单的观察,发现是树则 YES YES ,多于一个环则 NO NO
考虑只要一个环,不难发现以环上点为根不考虑环的树型结构,必然满足 a b a b . . . a b a b a b . . . a b 或者 a a a a . . a a a a a a . . a a
树哈希即可 O ( n log n ) O ( n log n ) 判断
[AGC045A] Xor Battle [AGC045A] Xor Battle
思路正确了,但是。。。
首先连续 0 0 或者 1 1 可以一起看,然后倒着用上帝视角决策
考虑 0 0 什么时候能赢,它的决策是后缀 0 0 代表的 A i A i 张成的线性基
倒着走,看 1 1 怎么为难 0 0 ,那就是出个不能被后面 0 0 线性基表示的数,有则 0 0 输了,否则必胜。
于是就是判某线性基是否能表示出另一线性基不能表示的数,直接把前一个线性基插入后一个看能否成功即可
但是胡乱写了个错的判断方法,没脑子
提交记录
[AGC045B] 01 Unbalanced [AGC045B] 01 Unbalanced
区间贡献是 0 , 1 0 , 1 数量的差,那么简洁的 0 , 1 0 , 1 视为 + 1 , − 1 + 1 , − 1
那么一个确定序列的答案就是 s m a x − s m i n s m a x − s m i n
于是考虑固定 s m a x s m a x ,最大化 s m i n s m i n
显然的贪心是先将 ?
看作 − 1 − 1 ,在 s m a x s m a x 不增大的情况下从前往后把 ?
从 − 1 − 1 翻成 + 1 + 1
这是 O ( n 2 ) O ( n 2 ) 的
然后开始观察,记 s m a x = M , f ( M ) = max s m i n s m a x = M , f ( M ) = max s m i n ,此时的答案为 M − f ( M ) M − f ( M )
注意到当 s m a x = M + 2 s m a x = M + 2 ,依据上述贪心,f ( M + 2 ) ≤ f ( M ) + 2 f ( M + 2 ) ≤ f ( M ) + 2
那么推出 M − f ( M ) ≤ M + 2 − f ( M + 2 ) M − f ( M ) ≤ M + 2 − f ( M + 2 )
于是只要对最大值理论下界和下界加一做上述贪心
提交记录
CF618F Double Knapsack CF618F Double Knapsack
猜一手从值域入手抽屉原理且必有解
但子集和相等很难弄
如果限制紧一些,比如区间和相等,那么还可做
而本题区间就足够了
接下来分析就很简洁且自然了(关键是限制到区间和)
分别做前缀和 A , B A , B ,需要找到 A i − A j = B k − B l ⟹ A i − B k = A j − B l A i − A j = B k − B l ⟹ A i − B k = A j − B l
分析它的值域和数量
不妨令 A i ≥ B k A i ≥ B k ,那么考虑临界处的 k k ,即最大的 k k 满足 B k ≤ A i B k ≤ A i
那么有 A i ≥ B k , A i < B k + b k + 1 ⟹ 0 ≤ A i − B k < b k + 1 ≤ n A i ≥ B k , A i < B k + b k + 1 ⟹ 0 ≤ A i − B k < b k + 1 ≤ n
而上述的 A i − B k A i − B k 有 0 ≤ i ≤ n 0 ≤ i ≤ n 即 n + 1 n + 1 对,由抽屉原理必有一对相等
注意这里令 A i ≥ B k A i ≥ B k ,为使 k + 1 k + 1 一定存在,也就是保证值域在 [ 0 , n − 1 ] [ 0 , n − 1 ]
那么 A n > B n A n > B n 时要交换 A , B A , B (然而我没这么做时也通过了) ,输出记得换回来啊
提交记录
[ARC122E] Increasing LCMs [ARC122E] Increasing LCMs
正序不好构造,考虑倒序构造,这时只需考虑一个数可不可行,之前的数无所谓顺序
直接枚举这个数看可不可行,找到一个即可用
因为 lcm lcm 单调不增,可用数集合大小一定单调不减,所以任选不劣
于是归纳到 n − 1 n − 1 的子问题
[ARC122D] XOR Game [ARC122D] XOR Game
从高往低确定,若当前位只能为 1 1 ,最优策略是找一对当前位为 0 0 和 1 1 的配对使得异或值最小
不然就分成两份继续做
[ARC070F] HonestOrUnkind [ARC070F] HonestOrUnkind
a ≤ b a ≤ b 肯定无解,只需 b b 中 a a 个人伪装成好人
a > b a > b ,只需找到一个好人就可询问 n − 1 n − 1 次确定所有人
因为好人人数多于坏人,所以用摩尔投票法,维护一个栈,用栈顶询问当前人
若回答 N
,那么删去这两人;否则入栈。最后栈顶即好人
提交记录
类似的方法可以求区间绝对众数,具体用个线段树维护这样的过程,最后验证求得的数是否是绝对众数
这样的思想也体现在了 P4062 [Code+#1]Yazid P4062 [Code+#1]Yazid 的新生舞会
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具