Codeforces Round #671(Div 2) 题解

A.
如果是(n)为奇数,那么是由先手决定留下哪个数,因此先手赢当且仅当至少有一个奇数位置是奇数.同理,如果(n)为偶数,后手赢当且仅当至少有一个偶数位置是偶数.
(居然写错得很离谱还能pp然后fst.)

B.
观察知当且仅当(n=2^k-1)时stairs是nice的.

C.
可以通过两次调整,先将(a[1,n-1])都变成(x),再将(a[n])变成(x).因此答案不超过(2),只需要讨论什么时候答案是(0)或者(1).
显然当且仅当(a[1,n]=x)时,答案为(0).
如果(a[1,n])中存在一个(x),那么可以把除这个元素之外的值都变成(x),答案为(1).
否则想要一次感染,只能把所有人同时变成(x),也就是(a[1,n])的平均数为(x),此时答案也为(1).

D.
排序,先从小到大从左到右填满偶数位置,再将剩下的数从小到大从左到右填到奇数位置.

E.
分类讨论.以下(p)(p_i)均指质数.
(n=p^k),任何排列答案都是(0).
(n=p_1p_2),任何排列答案都是(1).
(n=p_1^{r_1}p_2^{r_2}),其中(r_1)(r_2)大于(1),除(pq)(n)外,任何一个数被(p_1)(p_2)整除,将这些数分成两份,其中一份全能被(p_1)整除,另外一份全能被(p_2)整除,分别填到(pq)(n)中间以及(n)(pq)中间.
(n=p_1^{r_1}p_2^{r_2}cdots p_k^{r_k}),类似地,将所有(p_{i}p_{i+1})(包括(p_kp_1))作为分界点,剩下的数分成(k)份,其中第(i)份能被(p_i)整除,填入到(p_{i-1}p_i)(p_ip_{i+1})中间.

F.
先二分答案时间(t).
题意:给定时间(t)后,是否能再加至多一个点,在所有满足其中一维坐标相等,另外一维坐标相差不超过(t)的点之间连边,图能连通.
先在没有加点前求连通块.
1.如果连通块数量为(1,t)可行.
2.如果连通块数量大于(4,t)不可行.
3.如果连通块数量等于(2),直接(O(n^2))暴力判断是否存在属于不同连通块的两个点可以多加一个点连通:可能是两维坐标差都不超过(t),也可能其中一维坐标相等,另外一维坐标相差不超过(2t).
4.如果连通块数量等于(3)或者(4),那么新加入的点的横坐标一定是原来某个点横坐标.枚举横坐标,对于每个原来存在点而言,都存在一个纵坐标的范围使得这个点和新加入点直接相连:如果横坐标相等,纵坐标范围就是([y-t,y+t]);如果横坐标差不超过(t),纵坐标范围为([y,y]);否则不存在.
想象对于每个连通块,它都覆盖了某些坐标范围;如果存在一个点同时被所有连通块覆盖,那么说明这个点可以和所有连通块连通.
一种比较简单但暴力的方法:
a.先对所有纵坐标区间离散化;
b.定义两个可变长列表数组vector<int> in[maxn], out[maxm],然后对每个点,如果存在范围区间([L,R]),它所属的连通块是(c),in[L].push_back(c),out[R].push_back(c);
c.定义map<int,int> mp,遍历每个坐标(i),先for(int j: in[i])mp[j] += 1,如果此时mp.size()等于连通块数量,则(t)可行,然后for(int j: in[i]) if(not(mp[j] -= 1)) mp.erase(j).
复杂度是(O(n^2log nlog(2 imes10^9))),显然不科学,的确也不能过.

原文地址:https://www.cnblogs.com/Heltion/p/13698353.html