Codeforces Round #587 (Div. 3)(未完太困

尽管已经半夜了,还是有机会就补个题吧…
要学的东西太多了。


这场div3上了很多分,也是到目前为止rank最高的一次。因为前几个都是签到题(手速题),所以只要不犯糊涂(比如说打出一个控制字符然后WA到死)就比较容易拿到一个好rank。
A
偶数长度的前缀中要求出现0和1的个数相同,那么两位两位的处理、计数即可。

B
排序不等式的典型应用,逆序求和即可。

C
给定一张白纸、两张黑纸的坐标,试问白纸是否会被遮住。
仔细想了想后发现黑纸对白纸的有意义的影响其实只有两种,一种是完全覆盖,另一种是切断。可以料想,如果白纸没有被黑纸cut掉,那么这个不规则的形状仍然需要跟之前一样大的黑纸才能覆盖。所以我们分四类讨论,如果如果成功切断,更新白纸的坐标即可。这样子考虑两个黑纸的情况就可以得出答案。
值得一提的是,这种切断思想只能运用于两张黑纸覆盖的情况,因为上述提到的有意义其实只适用于“两张”,如果超过两张,那么不完全覆盖也是有可能有意义的。

CF题解的O(1)办法是求面积,如果下面的不等式成立,那么白纸就有空余。
在这里插入图片描述
不过我当时做的时候也想到了这个办法,但觉得求交集的面积好麻烦(其实很简答)…就放弃了。

提供一下CF题解上的代码:

pair intersect(pii a, pii b, pii c, pii d) {
	int lf, rg, up, dn;
	lf = max(min(a.x, b.x), min(c.x, d.x));
	rg = min(max(a.x, b.x), max(c.x, d.x));
	up = min(max(a.y, b.y), max(c.y, d.y));
	dn = max(min(a.y, b.y), min(c.y, d.y));

	if (rg <= lf || up <= dn) return { {0, 0}, {0, 0} };

	return { { lf, dn }, { rg, up } };
}

D
给定一串序列,可以对每一项加上k的倍数,对每一项操作若干次后要求这一串序列的值相同,求k的最大值以及对应的操作次数。
理解完模型后答案就呼之欲出了。可以看到的是,既然这些项距离某个“顶”的差值是k的倍数,那么这些项之间的差值肯定也是k的倍数了;又要求最大的k,那么显然就是求这些差值的gcd了。
当时对相邻项直接求gcd的合理性有过一些怀疑,不过还是考虑到了这独立的 n - 1个差值已经蕴含了n项所有需要的信息,所以相邻项直接求gcd非常正确且方便。

E、F
E询问的范围是1e9,F是1e18。
定义字符串s[i]是1、2、3、…、i 这些数字相连所组成的串,总串是s[1], s[2], …, s[n], …所连成的无限字符串。试问在这个无限字符串中,第x个字符是什么。
第一遍做的时候假了,把n >= 10的n都当作了一个字符…(naive!)后来还是执着于直接过1e18的F,搞了半天感觉头都搞晕了…但是也借此获得了暴力的算法(不)然后看了看剩下的时间不太够了就把E暴力莽过去了。

下面开始学习一下E、F的正解:
首先有个很容易想到的近似(但我因为假算法就是这么假戏真做的所以后来反而没有考虑到)第i个block至少有i个字符,那么可以据此可以把查询的上界确定下来。然后暴力遍历就可以获得E的一发AC。

你可能感兴趣的:(ACM,contest)