Codeforces Round #480 (Div. 2) C 贪心 D 数字、思维 E 树上倍增

[Codeforces Round #480 (Div. 2) ](Codeforces Round #480 (Div. 2) )

C. Posterized

题意:
给出 n 个数,都是区间 [0,255] 内的数,要你把 [0,255] 划分成多个长度 <=k 的不重叠的子区间。每个数必须包含在一个子区间内,且这个数的价值是这个子区间的左端点。要你输出这 n 数的价值,且这 n 个价值字典序要最小。
tags:
首先很明显字典序最小,那对于第 i 个数 p[i] 定它的区间时,左端点肯定要尽可能小。所以我们直接枚举区间 [ p[i]-k+1, p[i] ] 定左端点 l ,要这个区间内最大的后缀且没有被占用,即 [l, p[i]] 内的数都没被占用。
至于右端点,我们暂时就定在 p[i] 位置。
然后因为 l-1 位置肯定是另一个区间占用了,这时我们可以看看能否合并,即 l-1 位置的区间的左端点如果能拓展到 p[i] 位置,那么区间 [l, p[i]] 都可以合并到 l-1 位置的区间内。
代码:http://codeforces.com/contest/980/submission/38071053

D. Perfect Groups

题意:
给出 n (n<=5000) 个数(-1e8~1e8)。
先定义一个区间的价值为:这个区间内的数最少可以分成多少个集合,要求每个集合里的数两两相乘的积是完全平方数。
输出有多少个子区间的价值分别为 1、2、3、........ n 。
tags:
首先我们可以得到一个结论: 如果 a*b 和 a*c 都是完全平方数 ,那么 b*c 也是完全平方数。具体的可以分解质因子证明。
所以一个区间内的数要按题目要求划分成集合,那么集合之间肯定是不相交的。
这样的话,我们只要对于每个数定一下它包含在哪个集合里, 然后 O(n*2) 枚举一下区间,然后看区间有多少个集合就行,注意 0 要特殊修理。
另外,对于两个数要判断它们的乘积是否是完全平方数,我们不能有 sqrt() 判断,会超时。这里我们可以一直除它的质因子的平方,最后就只会剩下奇数次幂的质因子相乘。然后排个序,最后剩下的数相同,那就表明原来的数相乘是完全平方数。
代码:http://codeforces.com/contest/980/submission/38073629

E. The Number Games

题意:
n 个点的一棵树,标号是 1~n ,每个点的权值是 2^i 。要你删除掉 k 个点,删除之后剩下的点还是一棵连通的树,且要求剩下的点权值和最大。输出要删除哪些点。
tags:
因为 2^i > 2(i-1)+2(i-2) ....... + 1 ,所以我们必须贪心尽可能取更大的点。
所以总体的思路是很明显的,要删掉 k 个点,也就是要取出 n-k 个点。假设当前已经取的点连成的树是 G ,那么从点 n 到点 1 枚举,如果当前枚举的点到 G 的路径长度 <= 当前能够取的数量,那这条路径上的点就都可以取。
具体算路径长度,用倍增可以解决。以点 n 为根结点,tr[i][j] 表示点 i 往上走了 2^j 个点后到达的点 。
代码:http://codeforces.com/contest/980/submission/38084425

posted @ 2018-05-10 13:05  v9fly  阅读(182)  评论(0编辑  收藏  举报