CF practice #1solution
题目链接
A:cf 144 div
数据范围:n<=1000 , q(询问数量)<=105,a,b<=1016。
Solution:首先a,b是小于1016的,那么由此可知n不会超过80,否则和n=80没区别,然后分开考虑下面几种情况:
solve(n,a,b)=solve(n-2,a-|d(n-1)|,b-|d(n-1)|)
min(solve( n - 1 , a , b ) , min( solve( n - 1 , 1 , a ) + solve( n - 1 , b ,f[n-1] ) ,
solve( n - 1 , 1 , b ) + solve( n - 1, a , f[n-1] ) ) + 2 ) ;
B:cf 143 div2 C
题意:给n个数的一个序列,然后给一个操作次数k,每次操作可以选择一个数加1,问最后出现次数最多的数会出现多少次,这个数最小是多少。
Solution:把所有的数按照大小排序,有一个性质可以发现就是说某个数出现了x次的话,那么它一定是在当前序列中连续出现x次,那么可以二分出现的次数,然后判断该次数下是否有解。
C:cf 143 div2 D
题意:空间上给了一个以(0,0,0)为一个顶点的长方体,长方体每个面都平行于坐标面,每个面都有个数字,给一个长方体之外的坐标,问从这个坐标看过去看到的数字的和是多少。
D:cf 143 div2 E
题意:给一个n个点,m条边的无向图,保证每个顶点最多只属于一个简单环,给出q个询问,每个询问给出a,b问从a到b在每条边最多走一次的情况下有多少种不同的方案。
至于如何找两点之间的黑点数量,就是一个标准的lca问题了,对于两点是否在一个子树内,可以做一个虚拟的根0,连接每棵树的树根,最后如果询问两点的最近公共祖先是0的话,就表示不在一颗树内了。
复杂度为边双连通分量缩点O(n)加上lca的复杂度O(q*log(n)),总复杂度O(n+q*log(n))。
显然路径的总数与给出的点是否是关节点有关,上述方法不再有用,一个好的方法就是把原图按照点双连通分量缩点,关节点和普通点为白点,大于2个点的点双连通分量为黑点,其他照旧。
E:cf 142 div1 A
题意:给出一个n*m的矩阵,定义一步操作为把某一行向左或向右旋转一步,问最少的操作数使某一列均为1。如果不可能输出-1。
预处理出每一行把某一列置1的最小操作数,这个可以在O(N)的时间内完成,接着枚举每一列,然后把所有行的这一列置1的答案加起来,最后取最小的即结果。复杂度O(N*M)。
F:cf 142 div1 B
题意:给一个n个点m条边无向图,从一个点到另外一个点需要耗费一定的时间,每个点都有一个禁止出发的时间点的集合,如果在这个时间内在这个点,必须等到能出发才能出发去其他点,问从1到n的最短时间。
G:cf 142 div1 C
题意:一个n个点的完全图,一方把m条边涂成蓝色,其余的边均为红色,问全为红色和全为蓝色的三角形总数是多少。
Solution:三角形就三种:1.全红,2.全蓝,3.1红2蓝或1蓝2红。求1+2即求总三角形数量-3的数量。
H:cf 138 div1 A
题意:给出一串长为n的括号序列,由()[]构成,问你其中合法的有最多对[]的序列。
Solution:用栈扫描一遍序列,可以记录出每个右括号匹配的左括号的位置,及这段序列是否合法,这一步可以用O(N)的时间完成。
接下来只要再扫描一遍序列,找到所有合法的最长序列然后统计这个序列中中括号的数量更新答案就可以了,因为每段合法序列只会属于一个最长序列,所以复杂度为O(N)。
I:cf 138 div1 B
题意:给了一个母串和一个子串,问母串中的任一个字符是否都能属于某个和子串相等的子序列。
J:cf 138 div1 C
题意:给一个n个数的序列,每次操作把第i个数变成前一次序列中前i个数的和,问执行k次以后的序列每个数mod 109+7等于多少。
K:cf 140 div1 C
题意:在斐波拉契数列的第l项到第r项中,选出k个数,让这k的数的最大公约数最大。
L:cf 139 div2 D
题意:给一个n*m的地图,图上有一条贪吃蛇,走的规则和死亡规则和贪吃蛇游戏一样,给了一个苹果,问贪吃蛇最少多少步可以吃到苹果。吃不到就输入-1(苹果被墙围起来了等情况)。
M:cf 139 div2 E
题意:给了一个式子,问对于任意的正整数x和y,第n大的不可能出现的z是多少。
Solution:假设x为奇数,x=2*t-1,那么z=t+y+2ty-y,z=t*(2y+1),如果z不存在,那么z+1必为2的幂,即z=2k-1。
N:cf 137 div2 C
Solution:如果能知道所有数的分解情况的话,就可以知道该分式最后每个素数有多少个,这样的话很容易对每个数进行化简,得到最后结果,这部分不赘述。
关键是如何知道每个数的分解结果,如果每个数暴力分解的话,复杂度为O(N*),无法承受。不妨换种方式考虑。
对于每个数我们这样做的复杂度为O(20),因为每个数最多有20个素因子,总体下来复杂度为O(N*20)。加上筛素数的时间,复杂度为O(107+N*20)。
O:cf 137 div2 D
题意:有n个人,告知n个第一场比赛和第二场比赛的分数,每个分数属于某一个人,每人的分数为两场分数的和,最后按每人的分数进行排名,现在告诉你一个人最少得了x分,问他最好和最差的名次。
P:cf 137 div2 E
题意:给出m对字母关系,后一个字母不能出现在前一个字母后面,问一个长为n的序列,满足m对字母关系的有多少个。
数据范围:m<=52,n<=1012。序列由小写和大写字母组成。
Solution:字母总数只有52个,很容易做出一个52*52的转移矩阵,然后做一个n次的矩阵乘法就行,简单题。
Q:cf 136 div1 A
题意:给你一个包含n个元素的数列,问你能不能最多通过一次交换使得整个数列呈非降序排列。
Solution:读入数据后调用sort快排一遍,然后与原数据相比,发现有两个以上不同的数就输出NO,否则就输出YES即可。
R:cf 136 div1 B
题意:给一个长度为n个数的序列,m个操作,每个操作问从l到r的x的数量,x在l到r中正好出现了x次。
还有一种很简单的方法,1出现1次,2出现2次…a出现a次,因为序列长度最多也就105,所以合法的数的个数不会超过,可以预处理出这些数,然后对于每个询问暴力查询就可以了。复杂度O(m*)。
S:cf 136 div1 C
题意:给两个n个数的排列a和b,每次b向左旋转一位,问n次a和b的相同的数的距离最近是多少。
T:cf 134 div1 B
考虑a>>b的情况,这时会有很多个连续的T,那么这种情况我们可以用类似求最大公约数的方法把中间这一段求出来,这样的话,一次模拟的复杂度为O(logn)。总复杂度为O(nlogn)。
U:cf 134 div1 C
Solution:设状态为f[i][s],i表示以i为根节点的子树,s表示该子树的状态,子树的状态有3种:
1. 存在一个序列x,使f[i][x]=0且,f[i][-x]=0,-x表示x序列的反序列,即所有元素的取值均取反。记此状态为1。
2. 存在一个序列x,使f[i][x]=1且f[i][-x]=1,记此状态为2。
3. 存在一个序列x,使f[i][x]=0,f[i][-x]=1或f[i][x]=1,f[i][-x]=0。记此状态为4。
显然叶子为0,1,?分别对应了状态1,2,4。这三个状态是相互独立的,一个节点可能同时具有3种状态。
if ( ( ( x & 1 ) || ( y & 1) ) || ( ( x & 4 ) && ( y& 4 ) ) )
if ( ( ( x & 2 ) && (y & 4 ) ) || ( ( x & 4 ) && ( y & 2 ) ) || ( ( x & 4 )&& ( y & 4 ) ) )
if ( ( ( x & 1 ) && ( y & 1 ) ) )
if ( ( ( x & 2 ) || ( y & 2 ) ) || ( ( x & 4 ) && (y & 4 ) ) )
if ( ( ( x & 1 ) && ( y & 4 ) ) || ( ( x & 4 )&& ( y & 1 ) ) || ( ( x & 4 ) && ( y & 4 ) ) )
if ( ( ( x & 1 ) && ( y & 2 ) ) || ( ( x & 2 )&& ( y & 1 ) ) || ( ( x & 4 ) && ( y & 4 ) ) )
if ( ( ( x & 1 ) && ( y & 1 ) ) || ( ( x & 2 )&& ( y & 2 ) ) || ( ( x & 4 ) && ( y & 4 ) ) )
if ( ( ( x & 3 ) && ( y & 4 ) ) || ( ( x & 4 )&& ( y & 3 ) ) )
V:cf 133 div2 C
题意:一个图书馆,要雇管理员,要求每天都要有至少k个管理员,每个管理员都是工作n天,然后休息m天,要求任意相邻两天之间都有同一个管理员工作,问最少需要几个管理员,他们应该在什么时候被雇佣。
数据范围:1<=n,m<=1000,k<=1000,n!=1。
需要k*2+1个人,k个人在第一天,一个人在m+2天,k-1个人在m+1天。
需要k*2个人,k个人在第一天,一个人在m+2天,k-1个人在第m+1天。
需要4个人,一个第一天,一个第n天,一个第n*2-1天,一个第n*2天。
W:cf 133 div2 D
数据范围:3<=n<=1000,1<=ki<=105,1<=pij<=105,pij表示第i个空间的第j条线段到定点的距离,距离即其中一个结点的距离。
hint:不需要开1000*10^5的数组,只把第一组和第二组数记录下来即可,因为中间的变量并不需要保存。
X:cf 133 div2 E
题意:一个数字的根定义为g(x)=g(x的所有位之和),直到x只有一位数,现在给一个n位的k进制下的数字,问数字根恰好为b的子序列有多少个。