T1
100%
因为 b b b 和 d d d 都是正数,所以两边同时乘上 b × d b\times d b × d 后中间的符号不变。
所以只需要比较 a × d a\times d a × d 和 b × c b\times c b × c 的关系,如果 a × d > b × c a\times d>b\times c a × d > b × c 输出 >,如果 a × d < b × c a\times d<b\times c a × d < b × c 输出 <,如果 a × d = b × c a\times d=b\times c a × d = b × c 输出 =。
时间复杂度 O ( 1 ) O(1) O ( 1 ) 。
T2
60%
从 1 1 1 开始从小到大枚举整数 x x x ,找到最大的 x x x 满足 x 2 ≤ N x^2\leq N x 2 ≤ N ,答案即为 x 2 x^2 x 2 。
时间复杂度 O ( N ) O(\sqrt{N}) O ( N ) 。
100%
满足 x 2 ≤ N x^2\leq N x 2 ≤ N 的最大整数 x x x 实际上就是 ⌊ N ⌋ \lfloor \sqrt{N}\rfloor ⌊ N ⌋ 。
如果使用 sqrt \text{sqrt} sqrt 函数来求 ⌊ N ⌋ \lfloor \sqrt{N}\rfloor ⌊ N ⌋ ,会因为精度误差而出错,比如 sqrt ( 999999999999999999 ) \text{sqrt}(999999999999999999) sqrt ( 999999999999999999 ) 会被计算为 1000000000 1000000000 1000000000 。
所以要使用精度更高的 sqrtl \text{sqrtl} sqrtl 函数来计算。
计算 x = sqrtl ( N ) x=\text{sqrtl}(N) x = sqrtl ( N ) ,答案即为 x 2 x^2 x 2 。
注意:sqrtl \text{sqrtl} sqrtl 函数的返回值是实数类型的,将其赋值给一个 long long \text{long\ long} long long 类型的变量可以实现向下取整的效果。
时间复杂度 O ( 1 ) O(1) O ( 1 ) 。
T3
100%
在字符矩阵中,从外到内的第 i i i 层正方形,四条边对应的格子分别是:
第 i i i 行的第 i i i 列到第 n + 1 − i n+1-i n + 1 − i 列;
第 n + 1 − i n+1-i n + 1 − i 行的第 i i i 列到第 n + 1 − i n+1-i n + 1 − i 列;
第 i i i 列的第 i i i 行到第 n + 1 − i n+1-i n + 1 − i 行;
第 n + 1 − i n+1-i n + 1 − i 列的第 i i i 行到第 n + 1 − i n+1-i n + 1 − i 行。
从 1 1 1 到 ⌈ n 2 ⌉ \lceil \frac{n}{2}\rceil ⌈ 2 n ⌉ 枚举 i i i ,当 i i i 是奇数时将第 i i i 层正方形的四条边对应的格子赋值为 #;当 i i i 是偶数时将第 i i i 层正方形的四条边对应的格子赋值为空格。
完成所有赋值后再输出字符矩阵即可。
时间复杂度 O ( n 2 ) O(n^2) O ( n 2 ) 。
T4
20%
记最终合成白球的不同合成方案数量为 a n s w answ an s w ,最终合成黑球的不同合成方案数量为 a n s b ansb an s b 。
用 DFS \text{DFS} DFS 枚举每一轮合成选择的两个球的位置,共有 ( n − 1 ) ! (n-1)! ( n − 1 )! 种不同的位置选择方案。
每轮选好位置后,根据合成前这两个球的颜色,枚举合成的新球的颜色,继续 DFS \text{DFS} DFS 枚举剩下球的合成。
最终如果合成为一个白球则 a n s w answ an s w 增加一,合成为一个黑球则 a n s b ansb an s b 增加一。
时间复杂度 O ( ( n − 1 ) ! 2 n ) O((n-1)!2^n) O (( n − 1 )! 2 n ) 。
40%
对于测试点#3~4 ,因为所有球都是白球,所以每轮合成的新球的颜色一定为白色,最终一定合成为一个白球。
此时不同合成方案之间仅有每轮合成选择的两个球的位置不同,答案即为 a n s w = ( n − 1 ) ! answ=(n-1)! an s w = ( n − 1 )! ,a n s b = 0 ansb=0 an s b = 0 。
注意取模。
时间复杂度 O ( n ) O(n) O ( n ) 。
结合第一部分可以拿到 40 % 40\% 40% 的分数。
100%
定义 d p [ l ] [ r ] [ 0 ] dp[l][r][0] d p [ l ] [ r ] [ 0 ] 为将第 l ∼ r l\sim r l ∼ r 个球合成为一个白球的不同合成方案数量,d p [ l ] [ r ] [ 1 ] dp[l][r][1] d p [ l ] [ r ] [ 1 ] 为将第 l ∼ r l\sim r l ∼ r 个球合成为一个黑球的不同合成方案数量。
考虑将第 l ∼ r l\sim r l ∼ r 个球合成为一个球的最后一轮合成,本轮合成选择的两个球分别是第 l ∼ i l\sim i l ∼ i 个球合成出的球(称为球 A A A )与第 i + 1 ∼ r i+1\sim r i + 1 ∼ r 个球合成出的球(称为球 B B B ),那么本轮合成的新球的颜色与球 A A A 和球 B B B 的颜色有关,且球 A A A 的合成方案与球 B B B 的合成方案是独立的,合成球 A A A 所用的 i − l i-l i − l 轮合成与合成球 B B B 所用的 r − ( i + 1 ) r-(i+1) r − ( i + 1 ) 轮合成的相对顺序也是独立的。所以将第 l ∼ r l\sim r l ∼ r 个球合成为一个球的过程中,除最后一轮合成外剩下 r − l − 1 r-l-1 r − l − 1 轮合成中,选择合成球 A A A 的 i − l i-l i − l 轮合成的位置有 C r − l − 1 i − l \text{C}_{r-l-1}^{i-l} C r − l − 1 i − l 种选法。
用杨辉三角法预处理所有 0 ≤ i ≤ n 0\leq i\leq n 0 ≤ i ≤ n 且 0 ≤ j ≤ i 0\leq j\leq i 0 ≤ j ≤ i 的组合数 C i j \text{C}_i^j C i j 。
如果第 i i i 个球为白色,那么 d p [ i ] [ i ] [ 0 ] = 1 , d p [ i ] [ i ] [ 1 ] = 0 dp[i][i][0]=1,dp[i][i][1]=0 d p [ i ] [ i ] [ 0 ] = 1 , d p [ i ] [ i ] [ 1 ] = 0 ;如果第 i i i 个球为黑色,那么 d p [ i ] [ i ] [ 0 ] = 0 , d p [ i ] [ i ] [ 1 ] = 1 dp[i][i][0]=0,dp[i][i][1]=1 d p [ i ] [ i ] [ 0 ] = 0 , d p [ i ] [ i ] [ 1 ] = 1 。
对于 l < r l<r l < r 的情况,用三重循环进行区间DP:
第一重循环从 2 2 2 开始枚举区间长度 l e n len l e n ;
第二重循环枚举区间的左端点 l l l ,此时区间的右端点 r = l + l e n − 1 r=l+len-1 r = l + l e n − 1 ;
第三重循环在 l ∼ r − 1 l\sim r-1 l ∼ r − 1 中枚举 i i i 表示将第 l ∼ r l\sim r l ∼ r 个球合成为一个球的最后一轮合成选择的两个球分别是第 l ∼ i l\sim i l ∼ i 个球合成出的球 A A A 与第 i + 1 ∼ r i+1\sim r i + 1 ∼ r 个球合成出的球 B B B ;
这种情况下,除最后一轮合成外剩下 r − l − 1 r-l-1 r − l − 1 轮合成中,选择合成球 A A A 的 i − l i-l i − l 轮合成的位置有 C r − l − 1 i − l \text{C}_{r-l-1}^{i-l} C r − l − 1 i − l 种选法;
如果球 A A A 和球 B B B 颜色相同,以都是白色为例:最终只能合成出白球,球 A A A 的合成方案有 d p [ l ] [ i ] [ 0 ] dp[l][i][0] d p [ l ] [ i ] [ 0 ] 种,球 B B B 的合成方案有 d p [ i + 1 ] [ r ] [ 0 ] dp[i+1][r][0] d p [ i + 1 ] [ r ] [ 0 ] 种,合成对应的转移为 $dp[l][r][0]+=dp[l][i][0]\times dp[i+1][r][0]\times \text{C}_{r-l-1}^{i-l}$;
如果球 A A A 和球 B B B 颜色不同,以球 A A A 为白色且球 B B B 为黑色为例:可以选择最终合成出黑球或白球,球 A A A 的合成方案有 d p [ l ] [ i ] [ 0 ] dp[l][i][0] d p [ l ] [ i ] [ 0 ] 种,球 B B B 的合成方案有 d p [ i + 1 ] [ r ] [ 1 ] dp[i+1][r][1] d p [ i + 1 ] [ r ] [ 1 ] 种,合成对应的转移为 $dp[l][r][0]+=dp[l][i][0]\times dp[i+1][r][1]\times \text{C}_{r-l-1}^{i-l}$ 以及 $dp[l][r][1]+=dp[l][i][0]\times dp[i+1][r][1]\times \text{C}_{r-l-1}^{i-l}$。
答案即为 a n s w = d p [ 1 ] [ n ] [ 0 ] answ=dp[1][n][0] an s w = d p [ 1 ] [ n ] [ 0 ] ,a n s b = d p [ 1 ] [ n ] [ 1 ] ansb=dp[1][n][1] an s b = d p [ 1 ] [ n ] [ 1 ] 。
时间复杂度 O ( n 3 ) O(n^3) O ( n 3 ) 。
T5
20%
用 DFS \text{DFS} DFS 枚举知识点的 n ! n! n ! 种学习顺序,对于每种顺序判断是否为合法的学习方案,每当找到一种的学习方案,让答案增加一。
时间复杂度 O ( n ! n ) O(n!n) O ( n ! n ) 。
60%
因为每个知识点最多只会有一个前置知识点,可以把这类前置关系看成树的结构,p i p_i p i 是 i i i 的父节点。
用 d p [ i ] dp[i] d p [ i ] 表示只考虑以 i i i 为根的子树内的知识点时,合法的学习方案的数量。记 s i z [ i ] siz[i] s i z [ i ] 为以 i i i 为根的子树内的知识点的数量。
考虑知识点 x x x 有 m m m 个子节点,分别是 y 1 , y 2 , … , y m y_1,y_2,\dots,y_m y 1 , y 2 , … , y m 的情况下,如何计算 d p [ x ] dp[x] d p [ x ] 。
x x x 一定是第一个学习的知识点。对于以 x x x 的不同子节点为根的各子树,每个子树 的知识点对应的合法学习方案独立,不同子树 的知识点的相对学习顺序也是独立的:
以 y 1 y_1 y 1 为根的子树,有 s i z [ y 1 ] siz[y_1] s i z [ y 1 ] 个知识点需要学习,即需要从 s i z [ x ] − 1 siz[x]-1 s i z [ x ] − 1 个剩余的位置中,选出 s i z [ y 1 ] siz[y_1] s i z [ y 1 ] 个位置给子树 y 1 y_1 y 1 学习,这 s i z [ y 1 ] siz[y_1] s i z [ y 1 ] 个知识点对应的合法学习方案为 d p [ y 1 ] dp[y_1] d p [ y 1 ] ,共有 C s i z [ x ] − 1 s i z [ y 1 ] × d p [ y 1 ] \text{C}_{siz[x]-1}^{siz[y_1]}\times dp[y_1] C s i z [ x ] − 1 s i z [ y 1 ] × d p [ y 1 ] 种情况;
以 y 1 y_1 y 1 为根的子树,有 s i z [ y 2 ] siz[y_2] s i z [ y 2 ] 个知识点需要学习,即需要从 s i z [ x ] − 1 − s i z [ y 1 ] siz[x]-1-siz[y_1] s i z [ x ] − 1 − s i z [ y 1 ] 个剩余的位置中,选出 s i z [ y 2 ] siz[y_2] s i z [ y 2 ] 个位置给子树 y 2 y_2 y 2 学习,这 s i z [ y 2 ] siz[y_2] s i z [ y 2 ] 个知识点对应的合法学习方案为 d p [ y 2 ] dp[y_2] d p [ y 2 ] ,共有 $\text{C}_{siz[x]-1-siz[y_1]}^{siz[y_2]}\times dp[y_2]$ 种情况;
以此类推,以 y i y_i y i 为根的子树,有 s i z [ y i ] siz[y_i] s i z [ y i ] 个知识点需要学习,即需要从 s i z [ x ] − 1 − ∑ j = 1 i − 1 s i z [ y j ] siz[x]-1-\sum_{j=1}^{i-1}siz[y_j] s i z [ x ] − 1 − ∑ j = 1 i − 1 s i z [ y j ] 个剩余的位置中,选出 s i z [ y i ] siz[y_i] s i z [ y i ] 个位置给子树 y i y_i y i 学习,这 s i z [ y i ] siz[y_i] s i z [ y i ] 个知识点对应的合法学习方案为 d p [ y i ] dp[y_i] d p [ y i ] ,共有 $\text{C}_{siz[x]-1-\sum_{j=1}^{i-1}siz[j]}^{siz[y_i]}\times dp[y_i]$ 种情况;
所以 $dp[x]=\prod_{i=1}^{m}(\text{C}_{siz[x]-1-\sum_{j=1}^{i-1}siz[y_j]}^{siz[y_i]}\times dp[y_i])$。
用杨辉三角法预处理所有 0 ≤ i ≤ n 0\leq i\leq n 0 ≤ i ≤ n 且 0 ≤ j ≤ i 0\leq j\leq i 0 ≤ j ≤ i 的组合数 C i j \text{C}_i^j C i j 。
先进行第一次 DFS \text{DFS} DFS 计算出 s i z siz s i z 数组。
再进行第二次 DFS \text{DFS} DFS 计算 d p dp d p 数组:
初值为 d p [ x ] = 1 dp[x]=1 d p [ x ] = 1 ;
枚举 x x x 的子节点,当枚举到 x x x 的第 i i i 个子节点 y i y_i y i 时,维护 n u m = s i z [ x ] − 1 − ∑ j = 1 i − 1 s i z [ y j ] num=siz[x]-1-\sum_{j=1}^{i-1}siz[y_j] n u m = s i z [ x ] − 1 − ∑ j = 1 i − 1 s i z [ y j ] ,转移为 $dp[x]=dp[x]\times(\text{C}_{num}^{y_i}\times dp[y_i])$。
由于可能存在多个 p i = 0 p_i=0 p i = 0 的知识点,可以把 0 0 0 看成树的根,从 0 0 0 出发进行 DFS \text{DFS} DFS ,答案就是 d p [ 0 ] dp[0] d p [ 0 ] 。
算法的时间复杂度瓶颈在于用杨辉三角法预处理组合数。
注意:三个或更多的数相乘可能会超出 long long \text{long\ long} long long 范围,要及时取模。
时间复杂度 O ( n 2 ) O(n^2) O ( n 2 ) 。
100%
预处理模意义下阶乘 f a c [ i ] = i ! fac[i]=i! f a c [ i ] = i ! 和模意义下阶乘的逆元 i f a c [ i ] = 1 i ! ifac[i]=\frac{1}{i!} i f a c [ i ] = i ! 1 。过程中只需要在求 i f a c [ n ] ifac[n] i f a c [ n ] 时计算一次逆元。关于模意义下的逆元问题请同学们自行查阅资料。
在第二部分的基础上,将组合数的计算方式改为 $\text{C}_i^j=\frac{i!}{j!\times (i-j)!}=fac[i]\times ifac[j]\times ifac[i-j]$。
时间复杂度 O ( n ) O(n) O ( n ) 。
T6
10%
对于每个询问,对 x i x_i x i 依次进行第 L i ∼ R i L_i\sim R_i L i ∼ R i 个修改即可。
注意取模。
时间复杂度 O ( m n ) O(mn) O ( mn ) 。
30%
对于测试点#2~3 ,因为 a i = 0 a_i=0 a i = 0 ,所以不论对 x i x_i x i 依次进行第 L i ∼ R i − 1 L_i\sim R_i-1 L i ∼ R i − 1 个修改后的结果是多少,都会将结果乘上 a R i = 0 a_{R_i}=0 a R i = 0 再加上 b R i b_{R_i} b R i 。
因此第 i i i 个询问的答案为 b R i b_{R_i} b R i 。
时间复杂度 O ( n + m ) O(n+m) O ( n + m ) 。
结合第一部分可以拿到 30 % 30\% 30% 的分数。
50%
对于测试点#4~5 ,因为 b i = 0 b_i=0 b i = 0 ,所以对 x x x 进行第 i i i 个修改也就是令 x = x × a i x=x\times a_i x = x × a i 。
因此第 i i i 个询问的答案为 x i × ∏ j = L i R i a j x_i\times \prod_{j=L_i}^{R_i} a_j x i × ∏ j = L i R i a j 。
乘法具有结合律:计算三个整数相乘时,先把前两个数相乘,再和另外一个数相乘,或先把后两个数相乘,再和另外一个数相乘,结果不变。乘法的结合律可以推广到多个整数相乘的情况。
预处理 a i a_i a i 的前缀乘积 f [ i ] = ∏ j = 1 i a j f[i]=\prod_{j=1}^{i} a_j f [ i ] = ∏ j = 1 i a j ,以及模意义下 f [ i ] f[i] f [ i ] 的逆元 g [ i ] = 1 f [ i ] g[i]=\frac{1}{f[i]} g [ i ] = f [ i ] 1 。其中 g [ 0 ] = 1 g[0]=1 g [ 0 ] = 1 。
第 i i i 个询问的答案为 x i × f [ R i ] × g [ L i − 1 ] x_i\times f[R_i]\times g[L_i-1] x i × f [ R i ] × g [ L i − 1 ] 。
注意:三个或更多的数相乘可能会超出 long long \text{long\ long} long long 范围,要及时取模。
时间复杂度 O ( n + m ) O(n+m) O ( n + m ) 。
结合第一、第二部分可以拿到 50 % 50\% 50% 的分数。
100%
考虑对 x x x 先进行参数为 c c c 和 d d d 的修改,再进行参数为 e e e 和 f f f 的修改,结果为 $e\times(c\times x+d)+f=e\times c\times x+e\times d+f$。
也就是说,可以把先进行参数为 c c c 和 d d d 的修改再进行参数为 e e e 和 f f f 的修改的情况,合并为进行一个参数为 e × c e\times c e × c 和 e × d + f e\times d+f e × d + f 的新修改。
并且修改也具有结合律:依次进行三个修改时,先把前两个修改合并,再与另外一个修改合并,或先把后两个修改合并,再与另外一个修改合并,只要保证合并时修改间的相对位置不变 ,结果不变。修改的结合律也可以推广到多个修改依次进行的情况。
因此我们用线段树维护区间内修改依次合并出的新修改,可以用结构体来保存:t r e [ i ] tre[i] t re [ i ] 保存线段树上节点 i i i 对应的区间内的修改依次合并出的新修改,其中 t r e [ i ] . a tre[i].a t re [ i ] . a 表示这个新修改的参数 a a a ,t r e [ i ] . b tre[i].b t re [ i ] . b 表示这个新修改的参数 b b b 。
用 a s k ( x , L , R ) ask(x,L,R) a s k ( x , L , R ) 表示第 L ∼ R L\sim R L ∼ R 个修改依次合并出的新修改,a s k ask a s k 函数的返回值为结构体。
对于第 i i i 个询问,计算 a n s = a s k ( L i , R i ) ans=ask(L_i,R_i) an s = a s k ( L i , R i ) ,答案为 a n s . a × x i + a n s . b ans.a\times x_i+ans.b an s . a × x i + an s . b 。
时间复杂度 O ( n + m log ( n ) ) O(n+m\log(n)) O ( n + m log ( n )) 。