1.麦森数:
我们发现在 1 0 k ∼ 1 0 k + 1 − 1 , ( k ≥ 0 ) 10^k \sim 10^{k + 1}-1, (k \ge 0) 10k∼10k+1−1,(k≥0) 之间的数均有 k + 1 k + 1 k+1 位。因此对于任意正整数 x x x,它的位数是 ⌊ log 10 x ⌋ + 1 \lfloor \log_{10}x \rfloor + 1 ⌊log10x⌋+1。
而由于2的整次幂的末位数字不为0,因此 2 P − 1 2^P - 1 2P−1 的位数和 2 P 2^P 2P 的位数相同,所以 2 P − 1 2^P - 1 2P−1 的位数是 ⌊ log 10 2 P ⌋ + 1 = ⌊ P log 10 2 ⌋ + 1 \lfloor \log_{10}{2^P} \rfloor + 1 = \lfloor P\log_{10}2 \rfloor + 1 ⌊log102P⌋+1=⌊Plog102⌋+1。
cmath
库中有函数log10()
,直接使用即可。原地址。
那么在矩阵乘法中,若数组是从0开始作为下标的话: c [ ( i + j ) ] = a [ i ] ∗ b [ j ] c[(i+j)]=a[i]*b[j] c[(i+j)]=a[i]∗b[j],注意统计进位。
这里是代码的实现部分。
2.栈:
h ( n ) = 1 , 1 , 2 , 5 , 14 , 42 , 132 , 429 , 1430 , 4862 , 16796 , 58786 , 208012 , 742900 , . . . h(n)=1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, ... h(n)=1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,...
- h ( n ) = C 2 ∗ n n − C 2 ∗ n n − 1 h(n)=C_{2*n}^{n}-C_{2*n}^{n-1} h(n)=C2∗nn−C2∗nn−1
- h ( n ) = C 2 ∗ n n n + 1 h(n)=\frac{C_{2*n}^{n}}{n+1} h(n)=n+1C2∗nn
- h ( n ) = h ( 0 ) ∗ h ( n ) + h ( 1 ) ∗ h ( n − 1 ) + … … + h ( n − 1 ) ∗ h ( 1 ) + h ( n ) ∗ h ( 0 ) h(n)=h(0)*h(n)+h(1)*h(n-1)+……+h(n-1)*h(1)+h(n)*h(0) h(n)=h(0)∗h(n)+h(1)∗h(n−1)+……+h(n−1)∗h(1)+h(n)∗h(0)
- h ( n ) = ( 4 ∗ n − 2 ) ∗ h ( n − 1 ) n + 1 h(n)=\frac{(4*n-2)*h(n-1)}{n+1} h(n)=n+1(4∗n−2)∗h(n−1)
这是代码的实现部分。
3.乒乓球
在11分制下,一局比赛结束的条件是:某一方达到11分,且分差达到2;
在21分制下,一局比赛结束的条件是:某一方达到21分,且分差达到2;
这是代码的实现部分。
1.侦探推理
我们需要思考的是:
我们需要用什么作为我们判断一个人是否说谎的标准?我们显然是可以用阶乘的暴力枚举每一个人时候说谎,或者是用阶乘的暴力枚举究竟谁是罪犯?但是,我们真的需要这样吗?
我们可以发现的是在证词中还有另外的一个不相关的信息:星期几?换一个思路:如果我们是枚举的周几的话,是不是就可以直接判断一部分人是否说谎,这样子操作复杂度还低。
2.加分二叉树
问题:如何看出这是一个区间DP的??
1.FBI树
我们可以采用递归实现这个问题
例子:前序遍历
该节点的实现操作
(根)
dfs(l, mid)
(左节点)
dfs(mid+1,r)
(右节点)
这里是代码实现部分
2.火星人
组合数学中经常用到排列,这里介绍一个计算序列全排列的函数:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn
这里是代码的实现部分。
1.铺设道路
我们考虑一下把原序列变成是差分序列,那么这样的话,我们就会得到一个类似于这样的差分序列:-1 5 2 -3 4 正负交替的数字。我们知道的是如果是在[l, r]进行修改的话,我们只需要在 l 的位置,在 r+1 的位置上进行操作
因为 b a l a n c e d balanced balanced n u m b e r number number 的定义是:区间内的每一个数上的数字都要出现在区间和中。那么,当有两个数字上的位置数字冲突时就会在和 s u m sum sum 中组成一个新的数字,那么这个位置上的数字就不会再出现在和 s u m sum sum 上,所以此时的两个数字就可以组成 u n b a l a n c e d n u m b e r unbalanced \ number unbalanced number。
因为,我们要找到最小的一段不合法的数字的和,如果我们可以找到一段数字的话:也就说明了这一段数字中有至少两个数字在同一位上有同时出现的数字造就了他们的不合法。那么,我们贪心的选取的话,就是选取最少的数字组成最小的和,也就是可以只选取两个数字。
所以,我们的问题就转化成了:如何找到两个数字使得他们的和最小,这两个数字可选当且仅当他们最少有同一位置上数字同时出现。
因为这个问题是和数位有关系的,而且值域最大是 2 e 9 2e9 2e9,所以,我们可以单独的把每一个位置的数字拿出来处理。
因为题目中的操作是单点修改和区间查询,所以,我们要考虑可以实现这些操作的数据结构:这个时候就可以发挥线段树的作用了。
我们可以建10棵线段树动态维护每一个数字的删除,添加以及查询。
但是,有一个问题是:当我们知道了某两个数字在同一位置上有冲突的时候,如何确定这两个数字是我们要找的两个数字呢?