20210624一些杂题
今天做的是蒋神找的杂题(居然包括了昨天才结束的 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 lj≤k≤rj,将 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 1≤n≤200000。
- 1 ≤ q ≤ 200 000 1\le q\le 200\,000 1≤q≤200000。
分析 :
对于每一个位置来考虑,如果不要求 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]ai−mini∈[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 2≤n≤3⋅105。
- 1 ≤ m ≤ 3 ⋅ 1 0 5 1\le m\le 3\cdot 10^5 1≤m≤3⋅105。
分析 :
感觉这题做法肯定很多。任找一个点开始 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,考虑以下过程:
- 如果 S S S 包含某个 T j T_j Tj 作为子串,则结束过程。
- 否则,在 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 1≤n≤100。
- 1 ≤ n ⋅ m ≤ 10 000 1\le n\cdot m\le 10\,000 1≤n⋅m≤10000。
- 1 ≤ k ≤ 26 1\le k\le 26 1≤k≤26。
- 1 ≤ ∣ R ∣ ≤ 10 000 1\le |R|\le 10\,000 1≤∣R∣≤10000。
分析 :
建出 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 1≤n≤105。
- 1 ≤ q ≤ 1 0 5 1\le q\le 10^5 1≤q≤105。
分析 :
设答案等于 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 1≤n≤250000。
- 保证存在一个非空的宝藏集合满足题目的限制。
分析 :
先把一定不可能有宝藏的点删掉。然后找到直径的中点 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 1≤k≤500,在图 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 3≤n≤2000。
分析 :
先把标记正确的点删掉。再任选一个点 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(l′≤x<y≤r′),都有 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](1≤i≤k) 保持形状。
- 排列 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 u→v,都有 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(1≤k≤q),求出一个 k k k-编码最少拥有的边数。
- 1 ≤ n ≤ 25 000 1\le n\le 25\,000 1≤n≤25000。
- 1 ≤ q ≤ 100 000 1\le q\le 100\,000 1≤q≤100000。
分析 :
原题。考虑我们需要保留下来的边要满足什么,实际就是需要这两个点在每个区间按值排序后都相邻。由莫队算法我们可以知道,可能保留的边的个数是 O ( n q ) O(n\sqrt q) O(nq) 的。我们把这些边找出来,然后每次加入一个新的区间的时候把没有出现过的边加进去,考虑加进去的边什么时候会被删除,那就是第一个使这两个点不相邻的区间出现后就会被删除,这个不难求,不赘述了。