代码
快速幂
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
快速幂 | 求 a b m o d p a^b\mod p abmodp | 考虑将其拆解为二进制,再相乘。如 a 7 a^7 a7 为 a 2 0 × a 2 1 × a 2 2 a^{2^0}\times a^{2^1}\times a^{2^2} a20×a21×a22。 | 117 |
龟速乘
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
64位整数乘法 | 求 a b m o d p ab\mod p abmodp。 | 考虑类似于快速幂,即
7
a
=
a
+
2
a
+
4
a
7a=a+2a+4a
7a=a+2a+4a,也可以考虑根据
a
b
m
o
d
p
=
a
b
−
p
⌊
a
b
p
⌋
ab\mod p=ab-p\lfloor \frac{ab}{p}\rfloor
abmodp=ab−p⌊pab⌋,可以用 long double 存储中间值 a*b/p ,因为精度足够。用 long long 存储答案,因为即使是负的但只是高位的丢失。 | 118 |
期望
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
删树游戏 | 给一个 1 1 1 为根的树,每次随机选一个点,删去其子树,当选到 1 1 1 的时候结束,问期望操作次数。 | 期望操作次数 = = = 每个点期望被选次数之和。每个点是否被选只与它到根的链上第一个被选,假设有 x x x 个,概率为 1 x \frac{1}{x} x1。答案为所有深度的倒数之和。 | -30 |
容斥原理
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
GCD计数 | 给定 n , m n,m n,m 和长为 n n n 的 b b b 序列,求多少个序列 a a a 满足 1 ≤ a i ≤ m 1\le a_i\le m 1≤ai≤m 且 gcd ( a 1 , a 2 , a 3 , . . . , a i ) = b i \gcd(a_1,a_2,a_3,...,a_i)=b_i gcd(a1,a2,a3,...,ai)=bi。 | b i ≠ b i − 1 b_i≠b_{i-1} bi=bi−1 至多发生 log \log log 次,如果相等,填倍数即可。如果不等,令 g = b i − 1 g=b_{i-1} g=bi−1,求 [ 1 , ⌊ m b i ⌋ ] [1,\lfloor\frac{m}{b_i}\rfloor] [1,⌊bim⌋] 中与 g g g 互质数,容斥即可。 | -28 |
树上匹配计数 | 给定 2 n 2n 2n 个点的树,要求两两匹配。两个点能匹配当且仅当两点之间没有连边,问有多少种匹配方案 | 首先考虑坏匹配(即匹配为树边),这种边有 2 n − 1 2n-1 2n−1 条,我们要求的便是没有任意一条坏匹配的方案,可以先求出总方案,然后容斥处理坏匹配的个数,设有 x x x 个坏匹配,那用掉了 2 x 2x 2x 个点,剩余 2 n − 2 x 2n-2x 2n−2x 个点。令 g = 2 n − 2 x g=2n-2x g=2n−2x,则第一个点有 g − 1 g-1 g−1 种,第二个点有 g − 3 g-3 g−3 种,则答案为 ( g − 1 ) ! ! (g-1)!! (g−1)!!, ! ! !! !! 表示不超过这个正整数且与它有相同奇偶性的所有正整数乘积。然后考虑树形 DP。令 d p [ i ] [ j ] [ 0 / 1 ] dp[i][j][0/1] dp[i][j][0/1] 表示 i i i 及其子树内,坏匹配 j j j 对,根节点是否匹配的方案数。令 f j = d p [ 1 ] [ j ] [ 0 ] + d p [ 1 ] [ j ] [ 1 ] f_j=dp[1][j][0]+dp[1][j][1] fj=dp[1][j][0]+dp[1][j][1] 表示 j j j 对坏匹配的答案,则答案为 ∑ j = 0 n f j ( 2 n − 2 j − 1 ) ! ! ( − 1 ) j \sum_{j=0}^nf_j(2n-2j-1)!!(-1)^j ∑j=0nfj(2n−2j−1)!!(−1)j,而 d p dp dp 可以由树形 DP 求得,可以发现恰好能遍历到树上的每一对点,恰好是 O ( n 2 ) O(n^2) O(n2) 的。 | -29 |
筛质数
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
质数距离 | 求一个长度不超过 1 0 6 10^6 106 的区间 [ l , r ] [l,r] [l,r] 中相邻两素数差中最近的两个和最远的两个。 1 ≤ l < r < 2 31 − 1 1\le l<r<2^{31}-1 1≤l<r<231−1 | 普通筛法时间复杂度 O ( r ) O(r) O(r),显然不可取。考虑二次筛法。考虑到 2 31 − 1 ≈ 50000 \sqrt{2^{31}-1}≈50000 231−1≈50000,可以用线性筛筛出 50000 50000 50000 以内所有质数,然后用 1 ∼ 50000 1\sim 50000 1∼50000 中的素数用埃氏筛筛出给定区间内的素数,最后枚举即可。 | 114 |
数学
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
冬之花 | 给定 n n n 个数和 x x x,是否可以一直进行 x + a i x+a_i x+ai 的操作。 1 ≤ n ≤ 5 , 1 ≤ a b s ( x ) , a b s ( a i ) ≤ 100 1\le n\le 5,1\le abs(x),abs(a_i)\le 100 1≤n≤5,1≤abs(x),abs(ai)≤100 | 考虑不等的
a
i
a_i
ai 和
a
j
a_j
aj,则
x
+
a
i
≠
x
+
a
j
x+a_i\neq x+a_j
x+ai=x+aj,所以若其中一个的值为
0
0
0,则另一个必定
≠
0
\neq 0
=0。如果所有
a
i
a_i
ai 都相等,那么
x
x
x 变为
0
0
0 的充要条件是
x
x
x 与
a
i
a_i
ai 的正负性相反,并且
a
i
∣
x
a_i\mid x
ai∣x。注意对于每个
a
i
a_i
ai 判断最后一个充要条件,而不判断是否有不等
a
i
a_i
ai 的方法是错误的,如 1 2 2 -2 -1 ,显然可以一次
−
1
-1
−1,剩下都是
−
2
-2
−2。 | 62 |
AT220E | 给定一颗 2 n − 1 2^n-1 2n−1 个节点的满二叉树,输出树中距离 d d d 的点对个数。 1 ≤ d ≤ 2 × 1 0 6 , 2 ≤ n ≤ 1 0 6 1\le d\le 2\times 10^6,2\le n\le 10^6 1≤d≤2×106,2≤n≤106。 | 对于两点的位置关系分两种情况讨论。当前点为 i i i。① i i i 为点 u u u,往下走到达点 v v v,显然这个点的贡献就是 2 d 2^d 2d。② i i i下面是两个点 u , v u,v u,v,设左子树的路径长度为 l l l ,那么右子树的长度为 d − l d−l d−l,因为长度的分配,有 l − r + 1 l-r+1 l−r+1 种,因为这两条路径是固定的,所以剩下 2 d − 2 2^{d-2} 2d−2种方案。 | 63 |
CF1062B | 给定一个整数n ,您可以对它进行如下操作: 乘以x :把n乘上x(x是任意正整数)。开方:把n的值更新为
n
\sqrt{n}
n (前提是
n
\sqrt{n}
n必须为整数)。 您可以对这些操作进行零次至任意次。那么n可以达到的最小值是多少 ?达到最小值需要进行操作的次数又是多少?
1
≤
n
≤
1
0
6
1 \le n \le 10^6
1≤n≤106。 | 首先,我们要根据算术基本定理,分解质因子,因为开根的前提:根号 n n n 是整数,所以必定要保证每种质因子的数量一定为偶数(每次开跟将减少每种一半的质因子),因为我们可以乘上一个自然数,所以我们可以乘上一个数,使得所有质因子的数量都是 2 2 2 的幂次,这样就可以一直开根开到所有质因子数量均为 1 1 1为止,因此最小值肯定是每种质因子各一个连乘,最小值我们可以循环遍历到 n \sqrt n n看如果 n n n 被 i i i整除,那么最小值 × i \times i ×i(注意只乘 1 1 1 次),然后把 n n n 中所有的是 i i i 的质因子除去,于是再循环遍历到新的 n \sqrt n n(改变 n \sqrt n n是为了减少循环次数),循环结束如果 n n n 不为 1 1 1,那么再增加一种质因子。接下来我们要在各种质因子中选出数量最多的那种(循环里统计,还有因为我们不关心要乘上的 x x x 是多少,所以也无需数组记录各种质因子是哪些),找到大于等于最大值的最小的 2 2 2 的幂次,求幂次,所以我们可以直接对这个最大值进行求 log 2 \log2 log2操作,然后把结果向上取整就行了,于是结果就是乘上一次需要的次数 1 1 1+还要开几次根号 ⌈ ( log 2 ( max ) ⌉ \lceil(\log2(\max)\rceil ⌈(log2(max)⌉。注意点1.由于 1 1 1 不是质因子,所以我们要对它进行特判2.如果每种质因子数量 = 1 =1 =1,那么毫无疑问,直接输出 n n n和 0 0 0(这里我们要用一个变量来存原始的 n n n)。3.如果 n n n 为 4 , 9 , 36 , 100 4,9,36,100 4,9,36,100 这样各种质因子的数量本来就是 2 2 2 的幂次且全部质因子数量都相等(不等的话还是需要让所有质因子的数量相等才能开根,所以还是要乘)那么我们可以省掉乘 x x x 的操作,所以我们写个函数,遍历所有质因子数量,判断它们是否全部相等且是 2 2 2 的幂次。 | 65 |
删字符 | 长度为 n n n 的只含有 A,B,C \text{A,B,C} A,B,C 三种字符的字符串,选择连续的三个位置 ABC \text{ABC} ABC(必须按 ABC \text{ABC} ABC 的顺序来),如果 A \text{A} A 在目前串的奇数位置就删去 AC \text{AC} AC;否则删去 B \text{B} B,要求最大化可以执行的操作数。 1 ≤ 2 × 1 0 5 1\le2\times 10^5 1≤2×105 | 考虑一个 AAA … B … CCC \text{AAA\dots B\dots CCC} AAA…B…CCC 这样的一个子串,那么它最多可以贡献答案是 min ( A c n t , B c n t ) \min(A_{cnt},B_{cnt}) min(Acnt,Bcnt),但是如果 B \text{B} B 被删了,那么就不存在了。而可以通过删前面的 B \text{B} B 来改变后面的奇偶性,记前面有 k k k 个 B B B,现在的那么这个位置最多可以进行 min ( B c n t , A c n t , k + ( 1 − i m o d 2 ) + 1 ) \min(B_{cnt},A_{cnt},k+(1-i\mod 2)+1) min(Bcnt,Acnt,k+(1−imod2)+1)。还有一个细节,如果 k = 0 k=0 k=0 且 min ( B c n t , A c n t ) ≤ 1 \min(B_{cnt},A_{cnt})\le 1 min(Bcnt,Acnt)≤1 且这个位置是奇数,那么 k k k 是不能 + + ++ ++ 的。 | 71 |
简单的数学题 | T T T 组数据,求 C ( n , 0 ) 2 + C ( n , 1 ) 2 + . . . + C ( n , n ) 2 C(n,0)^2+C(n,1)^2+...+C(n,n)^2 C(n,0)2+C(n,1)2+...+C(n,n)2,对 1 0 9 + 7 10^9+7 109+7 取模。 T ≤ 1 0 5 , n ≤ 5 × 1 0 8 T\le 10^5,n\le 5\times 10^8 T≤105,n≤5×108, n > 1 0 7 n>10^7 n>107 的数据不超过 1000 1000 1000 组。 | 不难发现这个数列第 i i i ÷ ( i + 1 ) \div (i+1) ÷(i+1) 是卡特兰数,因为卡特兰数第 n n n 项是 n ! n ! ( n + 1 ) ! \frac{n!}{n!(n+1)!} n!(n+1)!n!,所以这里的结果就是 C ( 2 n , n ) C(2n,n) C(2n,n) 了。这里有 1000 1000 1000 组数达到了 5 × 1 0 8 5\times 10^8 5×108 级别,而直接打表会爆空间,怎么办呢?可以打 5000 5000 5000 个数字,分别表示 ( 2 × 1 0 5 ) ! , ( 4 × 1 0 5 ) ! , ( 6 × 1 0 5 ) ! , ⋯ , 1 0 9 ! (2\times 10^5)!,(4\times 10^5)!,(6\times 10^5)!,\cdots,10^9! (2×105)!,(4×105)!,(6×105)!,⋯,109!,然后单次查询时间复杂度最坏是 O ( 2 × 1 0 5 × 1 0 3 ) O(2\times 10^5\times 10^3) O(2×105×103),对于 n ≤ 1 0 7 n\le 10^7 n≤107 的话就直接预处理出 n ! n! n!,然后 O ( log n ) O(\log n) O(logn) 查询。 | 72 |
组合数
题目 | 题意 | 思路 | 代码 |
---|---|---|---|
[NOIP2016 提高组] 组合数问题 | 想知道如果给定 n , m n,m n,m 和 k k k,对于所有的 0 ≤ i ≤ n , 0 ≤ j ≤ min ( i , m ) 0\leq i\leq n,0\leq j\leq \min \left ( i, m \right ) 0≤i≤n,0≤j≤min(i,m) 有多少对 ( i , j ) (i,j) (i,j) 满足 ( i j ) m o d k = 0 \binom{i}{j}\mod k=0 (ji)modk=0。 0 ≤ n , m ≤ 2 × 1 0 3 0 \leq n, m \leq 2 \times 10^3 0≤n,m≤2×103, 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104 | 从 i i i 个数里选 j j j 个数的组合数就是杨辉三角的第 i i i 行第 j j j 列(行列均从 0 0 0 开始),直接递推求解。然后我们把每个组合数对 k k k 求余,如果当前这个组合数是 k k k 的倍数,那么这个位置值为 1 1 1 ,否则为 0 0 0 ,求一遍前缀和即可。 | 64 |
排队问题 | 有 n n n 人站在 m m m 站,排成 m m m 队。你不知道哪个人在哪个站,也不知道他们是按照什么顺序排队的,求不同方案的数量。 | 考虑每个人先排列再分队即可。 | -25 |
Two Arrays | 输入两整数 n n n、 m m m,求有多少对正整数序列 a i a_i ai、 b i b_i bi 满足:* a i a_i ai、 b i b_i bi 的长度为 m m m; a i a_i ai、 b i b_i bi 中所有元素的值小于等于 n n n;对于所有 1 ≤ i ≤ m 1\le i\le m 1≤i≤m, a i ≤ b i a_i\le b_i ai≤bi;序列 a a a 单调不降,序列 b b b 单调不升。答案对 1 0 9 + 7 10^9+7 109+7 取模。思路:考虑首尾相连,成了一个经典隔板法问题。 | 考虑首尾相连,成了一个经典隔板法问题。 | -26 |
棋盘问题 | 给定 n × n n\times n n×n 的网格图,要求放个棋子。一个格子能被某个棋子攻击到当且仅当有棋子跟它同行或者同列且它们之间没有其他棋子。问所有空格都能被攻击,且恰好有 k k k 对棋子能互相攻击的方案数。 | 考虑每行或每列只能放一个,又因为一行 x x x 个能攻击 x − 1 x-1 x−1 次,这样就可以得到应填上棋子的行数,然后用第二类斯特林数即可。 | -27 |