20210624一些杂题

这篇博客回顾了IOI2021的部分竞赛题目,包括分糖果问题的线段树解决方案、钥匙问题的DFS与图缩点技巧、字符串处理问题的AC自动机与高斯消元法,以及无向图和AND/OR查询的处理方法。分析了各类问题的关键思路和高效算法。
摘要由CSDN通过智能技术生成

今天做的是蒋神找的杂题(居然包括了昨天才结束的 IOI day1。

代码占篇幅就不贴了(其实就是我没写

然后体验感就是上个月才做的原题今天再看我已经不认识它了

占坑,先写一下口胡的分析吧,代码会争取写完的。


LOJ3523. 「IOI2021」分糖果

4s, 2048MB

给定长为 n n n 的数组 c i c_i ci。你有一个长为 n n n 的数组 a i a_i ai,初始时全 0 0 0。按顺序执行 q q q 次操作,每次操作是给定 l j , r j , v j l_j,r_j,v_j lj,rj,vj v j v_j vj 可能为负数),对所有 l j ≤ k ≤ r j l_j\le k\le r_j ljkrj,将 a k a_k ak 加上 v j v_j vj,然后对 c k c_k ck min ⁡ \min min,并对 0 0 0 max ⁡ \max max。求执行所有操作之后的数组 a i a_i ai

  • 1 ≤ n ≤ 200   000 1\le n\le 200\,000 1n200000
  • 1 ≤ q ≤ 200   000 1\le q\le 200\,000 1q200000

分析

对于每一个位置来考虑,如果不要求 a a a 要在 [ 0 , c ] [0,c] [0,c] 之间,那么 a a a 的变化就比较简单,我们记此时的 a a a i i i 时刻的值为 a i a_i ai ,考虑由 a i a_i ai 构成的序列。

我们求出这个序列中的最短的一个后缀 [ l , r ] [l,r] [l,r] ,满足 max ⁡ i ∈ [ l , r ] a i − min ⁡ i ∈ [ l , r ] a i > c \max_{i\in[l,r]}{a_i}-\min_{i\in[l,r]}{a_i}>c maxi[l,r]aimini[l,r]ai>c

这就意味着,如果后缀的第一个值是 max ⁡ \max max ,那么在取到 min ⁡ \min min 时实际的 a a a 0 0 0 。同理得如果第一个值是 min ⁡ \min min ,那么取到 max ⁡ \max max 时实际的 a a a 等于 c c c 。(这里是关键

然后就很简单了,拿线段树就可以维护,找后缀的时候在线段树上二分。


LOJ3524. 「IOI2021」钥匙

2s, 2048MB

给定一张 n n n 个点 m m m 条边的无向图,第 i i i 个点包含第 r i r_i ri 种钥匙,第 j j j 条边连接 u j u_j uj, v j v_j vj,且需要拥有第 c j c_j cj 种钥匙才能通过。注意不同点的钥匙种类可能相同,并且钥匙是无限使用的。到达一个点的时候就能得到这个房间的钥匙。设 p i p_i pi 为从 i i i 出发能到达的房间个数,求 p i p_i pi 最小的下标集合。

  • 2 ≤ n ≤ 3 ⋅ 1 0 5 2\le n\le 3\cdot 10^5 2n3105
  • 1 ≤ m ≤ 3 ⋅ 1 0 5 1\le m\le 3\cdot 10^5 1m3105

分析

感觉这题做法肯定很多。任找一个点开始 d f s dfs dfs ,一个点可以走向它一步即可到达的点,如果找到了环,那么就把环缩成一个新点,从新点开始继续 d f s dfs dfs ,最后答案就是没有出边的点中的 s i z e size size 最小的那个。关键是缩点时启发式合并,同时处理出可以通过的边。


GYM103119B. Boring Problem

1s, 512MB

给定 n n n 个长度都为 m m m 的字符串 T 1 , T 2 , … , T n T_1,T_2,\ldots,T_n T1,T2,,Tn。这些字符串(包括之后出现的字符串)都只包含前 k k k 个小写字母。对于给定的字符串 S S S,考虑以下过程:

  1. 如果 S S S 包含某个 T j T_j Tj 作为子串,则结束过程。
  2. 否则,在 S S S 之后以 p i p_i pi 的概率添加第 i i i 个小写字母,然后回到第 1 步。

定义 f ( S ; T , p ) f(S;T,p) f(S;T,p) 为过程结束时 S S S 的期望长度。

给定字符串 R R R,对每个 i = 1 , 2 , … , ∣ R ∣ i=1,2,\ldots,|R| i=1,2,,R,求出 f ( R [ : i ] ; T , p ) f(R[:i];T,p) f(R[:i];T,p) 1 0 9 + 7 10^9+7 109+7 取模后的结果。

  • 1 ≤ n ≤ 100 1\le n\le 100 1n100
  • 1 ≤ n ⋅ m ≤ 10   000 1\le n\cdot m\le 10\,000 1nm10000
  • 1 ≤ k ≤ 26 1\le k\le 26 1k26
  • 1 ≤ ∣ R ∣ ≤ 10   000 1\le |R|\le 10\,000 1R10000

分析

建出 AC 自动机, f i f_i fi 表示在点 i i i 的答案,对于每个点 i i i 都有方程 f i = 1 + ∑ j P j × f n e x t ( i , j ) f_i=1+\sum_jP_j\times f_{next(i,j)} fi=1+jPj×fnext(i,j) ,当然叶子节点的方程直接等于 0 了。

由于这是一个 AC 自动机,所以如果一个点的父亲只有它一个儿子,那么它的 f f f 值就可以用深度比它小的若干个点的 f f f 值表示出来。考虑 保留一些关键点,剩下的点的 f f f 值用关键点的值来表示。可以发现我们只需要保留 其父亲的儿子个数超过 1 1 1 的点,由于叶子节点的个数为 n n n ,所以保留的点的个数也是 O ( n ) O(n) O(n) 的,高斯消元即可。

(updata 6.25 单独写了详细版本的分析 在这里 ,因为这道题一个细节卡了我一下午


GYM103102H. AND = OR

3s, 1024MB

给定非负整数列 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,,an,有 q q q 次询问,每次询问给定 l i l_i li, r i r_i ri,判断 a l i , a l i + 1 , … , a r i a_{l_i},a_{l_i+1},\ldots,a_{r_i} ali,ali+1,,ari 能否分成两组,满足每一组都非空,且第一组所有数的 AND 等于第二组所有数的 OR。

  • 1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105
  • 1 ≤ q ≤ 1 0 5 1\le q\le 10^5 1q105

分析

设答案等于 k k k(就是让两边相等的值),那么所有 p o p c o u n t ( a i ) < p o p c o u n t ( k ) popcount(a_i)<popcount(k) popcount(ai)<popcount(k) 的数都在 OR 组,所有 p o p c o u n t ( a i ) > p o p c o u n t ( k ) popcount(a_i)>popcount(k) popcount(ai)>popcount(k) 的数都在 AND 组。且 p o p c o u n t ( a i ) = p o p c o u n t ( k ) popcount(a_i)=popcount(k) popcount(ai)=popcount(k) 的数必须相等,否则构造不出解。然后就可以随便做了,枚举 p o p c o u n t ( k ) popcount(k) popcount(k) ,用 st 表查出按位与和按位或的答案,最后判一下 p o p c o u n t popcount popcount 和答案相等数放哪一组即可。


GYM103102J. One Piece

3s, 256MB

给定一棵 n n n 个点的树。每个点上有独立的 1 / 2 1/2 1/2 概率存在宝藏。已知点 i i i 与所有宝藏的距离的最大值为 a i a_i ai,将所有点按照存在宝藏的概率从大到小排序,相同的按照编号从小到大排序。

  • 1 ≤ n ≤ 250   000 1\le n\le 250\,000 1n250000
  • 保证存在一个非空的宝藏集合满足题目的限制。

分析

先把一定不可能有宝藏的点删掉。然后找到直径的中点 m i d mid mid ,直径的长度为 l e n len len 。那么点 u u u 离距离它最远的宝藏的长度应为 d i s ( m i d , u ) + l e n / 2 dis(mid,u)+len/2 dis(mid,u)+len/2 ,显然非直径端点的点存在宝藏的概率为 1 / 2 1/2 1/2 ,且直径中点至少有两个儿子满足子树中存在直径端点有宝藏。所以对于一个直径端点,其对应的中点儿子子树的直径端点个数越多,它存在宝藏的概率就越小。然后这个题就做完了。

(然后实际上一开始不需要把不可能存在宝藏的点删掉,因为直径中点一定是 a i a_i ai 最小的点。


GYM103102C. 3-colorings

2s, 256MB

本题没有输入

请先构造一张不超过 19 19 19 个点的无向图 G G G,然后对每个 1 ≤ k ≤ 500 1\le k\le 500 1k500,在图 G G G 的基础上添加至多 17 17 17 条边得到图 G k G_k Gk,满足 G k G_k Gk 有恰好 6 k 6k 6k 种三染色的方案。

分析 :不想画图,略了。


CF1508D. Swap Pass

2s, 256MB

给定平面上 n n n 个点,保证没有三点共线。每个点上有一个标记 a i a_i ai a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,,an 1 , 2 , … , n 1,2,\ldots,n 1,2,,n 的一个排列。你可以进行任意次以下操作:

  • 选择两个点 i i i, j j j,交换 i , j i,j i,j 上的标记,并在 i i i, j j j 之间画一条线段。

你需要使得第 i i i 个点上的标记是 i i i,且任意两条线段不在除公共端点以外的点上相交。找到任意一个合法方案。

  • 3 ≤ n ≤ 2   000 3\le n\le 2\,000 3n2000

分析

先把标记正确的点删掉。再任选一个点 u u u ,然后每个点按和点 u u u 构成的直线的极角排序,排完序后挨着交换使得最后的置换是一个环,剩下的每次交换都和 u u u 换即可。


CF1508F. Optimal Encoding

7s, 1024MB

给定长为 n n n 的排列 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,,an 以及 q q q 个区间 [ l i , r i ] [l_i,r_i] [li,ri]

给出以下定义:

  • 排列 b 1 , b 2 , … , b n b_1,b_2,\ldots,b_n b1,b2,,bn 能够让区间 [ l ′ , r ′ ] [l',r'] [l,r] 保持形状,若对任意的 x , y ( l ′ ≤ x < y ≤ r ′ ) x,y\pod{l'\le x<y\le r'} x,y(lx<yr),都有 b x < b y b_x<b_y bx<by 当且仅当 a x < a y a_x<a_y ax<ay
  • 排列 b 1 , b 2 , … , b n b_1,b_2,\ldots,b_n b1,b2,,bn k k k-相似的,若 b b b 能够让所有区间 [ l i , r i ] ( 1 ≤ i ≤ k ) [l_i,r_i]\pod{1\le i\le k} [li,ri](1ik) 保持形状。
  • 排列 b 1 , b 2 , … , b n b_1,b_2,\ldots,b_n b1,b2,,bn 满足 DAG G ′ G' G,若对于 G ′ G' G 中的每条边 u → v u\to v uv,都有 b u < b v b_u<b_v bu<bv
  • 一个 k k k-编码是一张 DAG G k G_k Gk,使得排列 b 1 , b 2 , … , b n b_1,b_2,\ldots,b_n b1,b2,,bn 满足 G k G_k Gk 当且仅当 b b b k k k-相似的。

对每个 k ( 1 ≤ k ≤ q ) k\pod{1\le k\le q} k(1kq),求出一个 k k k-编码最少拥有的边数。

  • 1 ≤ n ≤ 25   000 1\le n\le 25\,000 1n25000
  • 1 ≤ q ≤ 100   000 1\le q\le 100\,000 1q100000

分析

原题。考虑我们需要保留下来的边要满足什么,实际就是需要这两个点在每个区间按值排序后都相邻。由莫队算法我们可以知道,可能保留的边的个数是 O ( n q ) O(n\sqrt q) O(nq ) 的。我们把这些边找出来,然后每次加入一个新的区间的时候把没有出现过的边加进去,考虑加进去的边什么时候会被删除,那就是第一个使这两个点不相邻的区间出现后就会被删除,这个不难求,不赘述了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值