本文为codeforces 1600分,顺序以过题人数为排序关键字的题目题解
目前已更新前50题
Problem - 431C - K-tree
标签:类似背包dp
思路:
- f[i][0/1]走到某一点时,表示总得分为i时,是否满足要求的路径
- 这一种分值可以从k种路线走过来,所以二重循环枚举 1 < j < m i n ( i , k ) 1<j<min(i,k) 1<j<min(i,k)
- 复杂度:O(n*k)
Good subarrays/1398/C
标签:数学推导
思路:
- 由原式可得: S r − S l − 1 = r − ( l − 1 ) S_r-S_{l-1}=r-(l-1) Sr−Sl−1=r−(l−1),进一步推导为 S r − r = S l − 1 − ( l − 1 ) S_r-r=S_{l-1}-(l-1) Sr−r=Sl−1−(l−1),所以从前往后不断扫描记录 S i − i S_i-i Si−i的相等情况即可。
- 复杂度:O(nlogn)
Problem - 371C - Hamburgers
标签:二分答案
思路:
- 如果是正向思考需要三个数字反复补缺,所以考虑验证答案。
- 于是可以每次验证是否能做这么多个汉堡来二分答案。
- 复杂度:O(logn)
Spreadsheet - CodeForces 1B - Virtual Judge (vjudge.net)
标签:进制转化
思路:
- 字母转化成数字毫无疑问,为26进制转化。
- 数字转化为字母,因为没有0,每个数字都是[1,26]。
-
n
u
m
=
∑
i
=
0
n
−
1
a
i
∗
2
6
i
num=\sum_{i=0}^{n-1}a_i*26^i
num=∑i=0n−1ai∗26i
=> n u m = a 0 + ∑ i = 1 n − 1 a i ∗ 2 6 i num=a_0+\sum_{i=1}^{n-1}a_i*26^i num=a0+∑i=1n−1ai∗26i( a 0 a_0 a0系数为1,所以原式等价为此式子)
=> n u m − 1 = a 0 − 1 + ∑ i = 1 n − 1 a i ∗ 2 6 i num-1=a_0-1+\sum_{i=1}^{n-1}a_i*26^i num−1=a0−1+∑i=1n−1ai∗26i
此时就转化为了26进制,不断除以26,就可以又得到 a i a_i ai - 推荐文章:没有0的进制 - 何太狼 - 博客园 (cnblogs.com)
Problem - 377A - Maze
标签:一般dfs
思路:
1.直接dfs,当有一个格子无法继续延伸的时候,就可以将这个格子填充为X
2.这题样例略弱,写了个错的代码仍未被hack,有兴趣的可以来看看。(错误链接:Submission #250448284 - Codeforces)
Problem - 1526C2 - Potions
标签:反悔贪心
思路:
- 如果到达某一个负数值的位置的时候, S S S小于了0,那么就去掉前面一个最小的负数。
- 可以使用优先队列实现该算法。
Problem - 1352G - Special permutation
标签:构造题
思路:
- 为了保证每个数字的间隔为2,所以可以想到分奇偶。
- 考虑对于3 1 4 2这个原式序列,如果在左边只放奇数,右边只放偶数,那么所形成的序列刚好满足要求
Problem - 1336A - Linova and kingdom
标签:树形dp
思路:
- 可以发现,从下到上设置关键节点是最优的。
- 其次如果将一个节点设置为关键节点,则会发现总权值将产生 d e p i − S i z i + 1 dep_i-Siz_{i}+1 depi−Sizi+1的变化,所以可以按照此式子进行排序,依次选择最小的子树的根进行设置。
Problem - 1363C - Game on leaves
标签:分类讨论
思路:
- 先手必胜:x在叶子节点上
- 发现胜利与否与x节点的度数和总结点的个数有关。
- 如果x的度数为m,总共有n个点,那么优先删除n-m-1个点,最后剩下m个点,可以推出,胜负只与n奇偶相关
Problem - 1353D - Constructing the array
标签:优先队列模拟
思路:
- 将区间不断地装入优先队列当中,按照左区间端点和长度排序。
Problem - 1358C - Celex update
标签:思维题
思路:
- 只向右走,再向下走可以发现能够找到最小和。
- 因为左下方的数字比右上方的数字大1,所以可以不断的将路线向左下移动,每次会将路线和加1。
- 最终就是(n-1)*(m-1)+1
Problem - 235A - Lcm challenge
标签:互质的应用
思路:
- 三个连续的数字中,如果中间的数字是偶数,那么三个数字必然互质,他们的lcm也是最大的。
- 如果中间的数字是偶数,那么n-1,n-2,n-3必然是中间为偶数的,但这不一定拥有最大的lcm,如果n,n-1,n-3是互质的,那么这种情况拥有更大的lcm,所以需要比较一下这两种情况。
- 不需要继续比较n,n-1,n-4,因为n-1,n-2,n-3的乘积已经大于这种情况的乘积了。
1.Problem - 1497C2 - K-lcm (hard version
标签:质因数分解类构造
思路:
- 如果三个数中有1,则不会改变lcm,此时另外两个数为 n − 1 2 \frac{n-1}{2} 2n−1可以满足,所以 n n n需要是奇数。
- 如果n是偶数,并且不能拆分出两个质因子2,那么 n 2 \frac{n }{2} 2n就是一个奇数,那么减1后就可以成为一个偶数,则与2求lcm仍为 n 2 − 1 \frac{n }{2}-1 2n−1。
- 如果能够拆分出两个以上质因子2,那么可以将n拆分成
n
2
\frac{n}{2}
2n,
n
4
\frac{n}{4}
4n,
n
4
\frac{n}{4}
4n,也就是分成四份,取两份,一份,一份。
总结一下就是: - 当为奇数时,输出1, n − 1 2 \frac{n-1}{2} 2n−1, n − 1 2 \frac{n-1}{2} 2n−1
- 当为偶数,
不能被4整除时,输出2, n 2 − 1 \frac{n}{2}-1 2n−1, n 2 − 1 \frac{n}{2}-1 2n−1
当能被4整除时,输出 n 2 \frac{n}{2} 2n, n 4 \frac{n}{4} 4n, n 4 \frac{n}{4} 4n
Problem - 1334C - Circle of monsters
标签:前缀和模拟
思路:
- 因为爆炸只会对后面的怪兽造成影响,所以有下面两种情况
- 要不将一个怪兽直接打死,要不将一个怪兽先用前面的炸残再打死。明显第二种最优,所以枚举1e3的起点,然后再模拟即可。
Orac and lcm/1349/A
标签:gcd/lcm与质因数分解的关系
思路:
- gcd本质上就是求一列数字的公共质因子的最小幂值,lcm本质上就是求一列数字的公共质因子的最大幂值。
- 所以综上所述,先求lcm会保留除了最小幂值的所有幂值,再求gcd实际就是求的所有公共质因子的次小幂值了。
- 注意,如果有一个数字没有p的幂值,那么可以算成p为0的情况,但是不能有超过两个数字没有p这个质因子。
Row gcd/1458/A
标签:更相减损法gcd
思路:
- 这道题主要是更相减损法的应用。
- g c d ( a i + a j , a i + 1 + a j , a i + 2 + a j . . . ) gcd(a_i+a_j,a_{i+1}+a_j,a_{i+2}+a_j...) gcd(ai+aj,ai+1+aj,ai+2+aj...)= g c d ( a i + a j , a b s ( a i + 1 − a i ) , a b s ( a i + 2 − a i + 1 ) . . . ) gcd(a_i+a_j,abs(a_{i+1}-a_i),abs(a_{i+2}-a_{i+1})...) gcd(ai+aj,abs(ai+1−ai),abs(ai+2−ai+1)...)
- 所以通过差分操作可以减去所有 a j a_j aj的影响,将原式转化为 a i + a j a_i+a_j ai+aj与后面n-1项差值的gcd
Problem - 1389B - Array walk
标签:dp
思路:
- dp[i][z],表示的是到第i个点的时候已经向左走了z步。
- d p [ i ] [ z ] = m a x ( d p [ i + 1 ] [ z − 1 ] + n u m s [ i + 1 ] , d p [ i − 1 ] [ z ] + n u m s [ i ] ) dp[i][z]=max(dp[i+1][z-1]+nums[i+1],dp[i-1][z]+nums[i]) dp[i][z]=max(dp[i+1][z−1]+nums[i+1],dp[i−1][z]+nums[i])
- 注意j+2*i-1=k的时候到达终点。
Problem - 706C - Hard problem
标签:dp
思路:
- dp[i][0/1]表示第i个字符串是否反转所产生的体力值。
- dp[i][0/1]可以从dp[i-1][0/1]的转移,其中的限制是否大于前面的字符串。
Problem - 1344A - Hilbert’s hotel
标签:看不懂了,忘记之前怎么做了
思路:看不懂了,忘记之前怎么做了
Problem - 1165D - Almost all divisors
标签:分解因数的水题
思路:
- 分解一下因数,个数必须等于n。
- 数列排序后,对称位置必须乘积一样。
Fox and names/510/C
标签:拓扑排序模板题
思路:
- 按照当前所排顺序建立拓扑有向图,然后跑一遍拓扑排序即可。
Problem - 1396A - Multiples of length
标签:构造题
思路:
- 只需要三次操作,最后一次操作一定是将所有数字变为0,那么就考虑如何将所有的数字通过两次操作变成一个数字的倍数。
- 可以选前n-1个数字,将前n-1个数字变成n的倍数,然后再将最后一个数字变成n-1的倍数。
Maximum sum on even positions/1373/D
标签:优先队列优化dp
思路:
- 题意可以转化为找一个区间,这个区间的偶数与这个区间的奇数和差值最大。
- 由于反转的特性,奇数位置起点的反转长度必须是偶数才能有贡献,偶数位置起点的反转场长度必须是奇数才能有贡献。
- 所以可以将前缀和数组改为奇偶位置差的前缀和数组,即奇数位置减去这个值,偶数位置加上这个值。
- 然后对于一个奇数位置,它肯定是要找它后面区间差值最大的偶数位置作为区间终点。所产生的贡献为q.top()-sum[i-1]。
- 所以我们考虑优先队列模拟这一过程,然后如果l>优先队列中的 t o p ( ) p o s top()_{pos} top()pos,就直接pop()掉即可
Problem - 1519D - Maximum sum of products
标签:中心区间枚举扩散式优化
思路:
- 对于长度为2的区间改变所产生的贡献: a i ∗ b i + 1 − b i ∗ a i + 1 − a i ∗ b i + a i + 1 ∗ b i + 1 = ( a i − a i + 1 ) ∗ ( b i + 1 − b i ) a_i*b_{i+1}-b_i*a_{i+1}-a_i*b_i+a_{i+1}*b_{i+1}=(a_i-a_{i+1})*(b_{i+1}-b_{i}) ai∗bi+1−bi∗ai+1−ai∗bi+ai+1∗bi+1=(ai−ai+1)∗(bi+1−bi)。
- 发现如果中心的区间保持反转的情况下,加入两个端点后的新贡献等于端点之差的乘积。
- 所以可以通过单数字和双数字种子区间向外扩散更新。
Problem - 1348C - Phoenix and distribution
标签:构造题
思路:
- 如果最小的字母少于k个,那么排字典序时最大的那个必然为第一个字母较大者,所以ans为单个非最小字母
- 如果后n-k个字符全部一样,那么平均分配会更好。
- 如果n-k个字符不全部一样,如果平均分配则会让后面更大的字符更快的出现在前面,所以将剩余字符全部加到一个串里。
Problem - 1514C - Product 1 modulo n
标签:同余数论
思路:
- 乘积表达式为: k ∗ n + 1 k*n+1 k∗n+1,这必然与n互质,所以乘积序列中的每个数字都要与n互质。
- 如果全部与n互质的数字相乘在一起最终结果s不为1,那么就去除掉这个结果数s即可了。
Problem - 1234D - Distinct characters queries
标签:线段树
思路:
- 当然可以建26棵线段树喽。
- 更简洁的方法是用26位01串表示该位置是否存在该字母,然后通过|(或)操作来求不同线段区间的是否存在该字母。
Parsa’s humongous tree/1528/A
标签:树形dp
思路:
- 可以发现每个节点要不取左端要不就是取右端。
- 所以就变成了树形dp[i][0/1],这两种情况进行转移。
Problem - 1342C - Yet another counting problem
标签:构造题(循环+取模特点)
思路:
- x%a%b和x%b%a的值是循环的
- 这个循环的大小是lcm(a,b)
- 所以预处理1-lcm(a,b)的贡献值即可。
Problem - 1374E1 - Reading books (easy version)
标签:思维构造
思路:
- 每个人都需要k本书,可以将两本只能个人读的书合并成一本两个人都可以读的书。
Problem - 1395C - Boboniu and bit operations
标签:背包dp
思路:
- 因为数据范围最大只有 2 10 2^{10} 210,所以可以类比二维背包dp。
- dp[i][k] 表示的是使用到第i件物品的时候,得分为k的情况。
- d p [ i ] [ k ∥ ( a [ i ] & b [ j ] ) ] ∥ = d p [ i − 1 ] [ k ] dp[i][k\| (a[i]\&b[j])] \|=dp[i-1][k] dp[i][k∥(a[i]&b[j])]∥=dp[i−1][k]
Problem - 1305C - Kuroni and impossible calculation
标签:鸽巢定理
思路:
- 如果有两个数%m的情况下同余,那么一定会产生m的倍数的差值。
- 如果有超过m个数字,那么必然有2个数字有相同的余数。所以n的范围如果大于m则答案只能是0。
- 至于其他的小范围,直接模拟即可了
Problem - 1542C - Strange function
标签:容斥定理,lcm思维
思路:
- 可以发现,f(x)=i,则lcm(1,2…i-1)|x
- 满足 L i L_i Li|num的数字个数为, n = 下取整 n L i n=下取整\frac{n}{L_i} n=下取整Lin。
- 满足 L i + 1 L_{i+1} Li+1|num的数字个数为, m = 下取整 n L i + 1 m=下取整\frac{n}{L_{i+1}} m=下取整Li+1n。
- 所以满足只被 L i L_i Li整除,而不被 L i + 1 L_{i+1} Li+1整除的数字就是n-m。
- 所以不断累加即可
Problem - 1527C - Sequence Pair Weight
标签:子段计数操作(中心扩散)
思路:
- 对于两个相同的数字 p o s i , p o s j pos_i,pos_j posi,posj来讲,起点有 n = p o s i n=pos_i n=posi个数字选择,它后面有 m = n − p o s j + 1 m=n-pos_j+1 m=n−posj+1个数字选择,所以包含他的子段就是m*n个子段
- 但是不能枚举每个相同的数字的位置,这样是 n 2 n^2 n2的。
- 可以发现,对于三个数字的位置 p o s i , p o s j , p o s k pos_i,pos_j,pos_k posi,posj,posk,对于 p o s k pos_k posk的数字,有 ( n − p o s k + 1 ) ∗ ( p o s i + p o s j + p o s k ) (n-pos_k+1)*(pos_i+pos_j+pos_k) (n−posk+1)∗(posi+posj+posk)
Problem - 1327C - Game with Chips
标签:思维构造题
思路:
- 可以先将所有的球都放到某一个角落
- 然后再遍历所有的位置。
- 总计需要 ( 2 n − 1 ) ∗ ( m − 1 ) < 2 n m (2n-1)*(m-1)<2nm (2n−1)∗(m−1)<2nm
Problem - 1513C - Add one
标签:线性dp(爬楼梯)/打表找规律
思路:
- 发现每个数字最后都要到达10,所以我们最后只需要预处理出10的m次操作后的长度即可。
- 经过打表发现,第i个数字就是第 s i − 9 + s i − 10 s_{i-9}+s_{i-10} si−9+si−10两个字符串拼接而成。
- 所以: f i = f i − 9 + f i − 10 f_i=f_{i-9}+f_{i-10} fi=fi−9+fi−10
Problem - 1603B - Moderate Modular Mode
标签:取模构造(取模转化减法)
思路:
- 如果一个数x%y且kx<y<(k+1)x,则x%y=abs(y-x)。
- x>y,构造n=x+y。
- x=y,构造n=x。
- x<y,设kx<y<(k+1)x,所以此时如果有kx<n<y,则 r 1 = n − k x r_1=n-kx r1=n−kx, r 2 = y − n r_2=y-n r2=y−n,所以 n = k x + y 2 n=\frac{kx+y}{2} n=2kx+y。
Problem - 1503A - Balance the Bits
标签:构造题
思路:
- 1的个数必须偶数,前一半为(,后一半为)
- 总数必须偶数
- 首尾必须1
- 第奇数个0为(,第偶数个1为)
Problem - 343B - Alternating current
标签:栈模拟
思路:
- 如果相邻的两个是一样的就可以小曲解开了
- 这题真不好读懂
Problem - 1633D - Make them equal
标签:背包dp
思路:
- 可以先通过背包dp预处理出每个对位数字的转化次数
- 然后再通过背包dp得到k个金币选择哪些物品能达到最大价值
Problem - 1371D - Grid-00100
标签:构造题
思路:
- 可以发现对角线是不会增大答案的
- 然后继续构造可以选择(j,(j+i)%n)的位置进行填充
- 答案不是2就是0
Problem - 1475E - Advertising Agency
标签:组合数学
思路:
- 水题,看似背包dp,其实最大的那m<k类数必须选择,而选择会超过k的那部分,则是 C a l l k − m C_{all}^{k-m} Callk−m
Problem - 1707A - Doremy’s iq
标签:反悔贪心
思路:
- 考虑第一个选的位置是 p o s i pos_i posi,如果到 p o s j pos_j posj的位置上刚好智商为0的话,那么其实可以交换 p o s i , p o s j pos_i,pos_j posi,posj即选j,不选i,这样可以让从i+1到j的这中间有更大的可能不花费就可以参加比赛。
- 所以假设最后一个比赛时智商为0,然后倒序,遇到智商不够的场次智商就加1,直到智商等于q。
- 或者二分起始点的位置,也可以得到答案。
Problem - 1364C - Ehab and Prefix MEXs
标签:构造题
思路:
- 每个第一次出现的数字的对应位置是必须放置前面的数字的。
- 然后其余的是未确定的位置,如果一个位置的数字是i,那么前面未确定的位置和确定的位置需要填上1到i-1的数字。
- 可以使用队列辅助实现
Problem - 735D - Taxes
标签:哥德巴赫猜想
思路:
- 如果是质数则输出1
- 如果是偶数,则可以分解成两个质数的和
- 如果n-2是质数,则输出2,如果n-2不是质数,则输出3,因为n-3是偶数,可以拆成3个质数的和
Problem - 348A - Mafia
标签:贪心模拟
思路:
Problem - 1295C - Obtain The String
标签:二分查找
思路:
- 将每种字母的位置记录下来
- 然后不断地二分搜索pos后面的最近位置。
- 然后模拟记录所需要的趟数
Problem - 372A - Counting kangaroos is fun
标签:思维贪心
思路:
- 缩减的数量不会少于n/2
- 所以从最后面开始找,每次装下最大的可以装的袋鼠
Problem - 1437D - Minimal height tree
标签:bfs模拟
思路:
- 因为是升序排列,所以每次遇到逆序就需要新用一个子节点承接
- 所以遇到升序就子节点++,遇到逆序就子节点–
- 子节点用完就新开一层节点。
Problem - 446A - Codeforces
标签:预处理dp
思路:
- 先预处理出以这个点为结尾的最长上升子序列,再预处理出以这个点为起点的最长上升子序列。
- 然后如果abs(nums[i-1]-nums[i+1])>1,就可以尝试将两边拼接起来,更新ans