清北学堂 2020 国庆J2考前综合强化 Day5

1. 题目

T1 a

题目描述

题目描述

给一个仅包含字符 .* 的字符串。问是否存在 3*,它们的位置构成等差数列。

输入格式

第一行一个整数 n 表示字符串长度。
第二行一个字符串。

输出格式

yesno 表示是否存在。

样例输入 1

5
..***

样例输出 1

yes

样例输入 2

5
*..**

样例输出 2

no

数据规模

  • 对于 50% 的数据,n50
  • 对于 100% 的数据,n5000

Sol

sb 题,直接枚举两个数算出第三个数再 check 即可

T2 b

题目描述

题目描述

给一棵树,点黑白染色。现在要断开若干条边,使得每个连通块都恰好包含一个黑点。问有多少种方案。

输入格式

一行一个整数 n 表示点数。

接下来一行 n1 个数表示点 1,,n1 的父亲节点(点从 0 开始编号)。

接下来一行 n 个数(01)表示点的颜色,其中 0 表示白色,1 表示黑色。

输出格式

一行一个数表示答案。答案对 109+7 取模。

样例输入 1

3
0 0
0 1 1

样例输出 1

2

数据规模

  • 对于 40% 的数据 n10
  • 另有 30% 的数据 n500
  • 对于 100% 的数据 n105

Sol

树形 dp。

dpu,0 表示以 u 为根的子树满足题意且 u 所在的连通块不包含黑点的方案数。
dpu,1 表示以 u 为根的子树满足题意且 u 所在的连通块包含黑点的方案数。

然后直接枚举边 uv 背包转移即可。

即:

dpu,1=dpu,1(dpv,0+dpv,1)+dpu,0dpv,1

dpu,0=dpu,0(dpv,0+dpv,1)

T3 c

题目描述

时间限制 2s

题目描述

给一个序列 a1,,anQ 次询问,每次给出 l,r,要求回答

i=lr(sumj[l,i]aj×maxj[l,i]aj)

注:

为求和符号,i=LRxi=xL+xL+1++xR

sum 含义一样,sumj[L,R]xi=i=LRxi

maxj[L,R]=max(xL,xL+1,,xR),表示 x 数组在区间 [L,R] 的最大值。

输入格式

第一行一个整数 n

第二行 n 个整数表示序列 a1,,an

第三行一个整数 Q

接下来 Q 行,每行两个整数 l,r表示一个询问。

输出格式

Q 行,每行一个数表示答案,对 109+7 取模。

样例输入 1

5
4 6 1 7 9
2
1 5
2 4

样例输出 1

511
176

数据规模

  • 对于 30% 的数据,n,Q3000
  • 另有 30% 的数据,n,Q105
  • 对于 100% 的数据,n,Q1060ai109

本题 IO 量较大,请视情况斟酌 IO 方式。

Sol

O(n2) 暴力可以获得 30pts .

对序列直接建线段树,每个节点直接维护区间是当前节点所代表区间时的答案。预处理可以暴力 O(nlogn) 做。

询问的时候考虑把询问拆成 O(logn) 段区间,然后合并。

考虑把 [l,r] 拆成 [l,m][m+1,r]

A=i=lmaiB=maxj[l,m]aiC[l,m] 的答案。

则询问 [l,r] 的答案为:

i=lr(sumj[l,i]aj×maxj[l,i]aj)=C+i=m+1r(sumi[l,i]aj×maxj[l,i]aj)=C+i=m+1r((A+sumj[m+1,i]aj)×max{B,maxj[m+1,i]aj})

Si=sumj[m+1,i]ajMi=maxj[m+1,i]aj,则上式变为:

C+i=m+1r((A+Si)×max{B,Mi})

对于上式的 max{B,Mi} 那一项,容易发现它的取值是前面一段都等于 B,后面一段都等于 M,考虑二分出一个位置 t,使得 it:BMii>t:B<Mi,那么上式变为:

C+i=m+1r((A+Si)×max{B,Mi})=C+i=m+1((A+Si)B)+i=t+1r((A+Si)Mi)=C+AB(tm)+Bi=m+1tSi+Ai=t+1rMi+i=t+1rSiMi

因此只要对每段维护 Si,MiSi 的前缀和,Mi 的后缀和与 SiMi 的后缀和即可。

时间复杂度 O(nlog2n),60pts .

对序列建出区间最大值的笛卡尔树。

对于询问 [l,r],所有可能的最大值都出现在 llca(l,r) 的路径上。

考虑这条路径上的每一个点 u,容易发现,如果 u 是父亲的右儿子,则没有任何一个 i 满足 maxj[l,i]aj=au。如果 u 是父亲的左儿子,那么所有满足 maxj[l,i]aj=aui 恰好是那些 u 的右子树中的点。

即区间前缀和为 Si,则:

i=lr(sumj[l,i]aj×maxj[l,i]aj)=i=lr(SiSl1)×maxj[l,i]aj

那么只要维护 i=lrSi×maxj[l,i]aji=lrmaxj[l,i]aj 即可。

这个直接对到根路径再做一个前缀和就行了。

预处理 lca,复杂度 O(nlogn+Q),100pts .

T4 d

题目描述

时间限制 4s

题目描述

一张无向图,边上有边权。每个点至少有两条邻边,且邻边的边权互不相同。

起初时刻 t=0,每个点上有一个人。每到一个新的时刻,每个人都会选择相邻的边权最大的边走过去。但如果这条边是回头路(上一个时刻通过这条边走到当前点),那么这个人就不会选择这条边权最大的边,而会选择次大的边。

现在有 Q 组询问,每个询问给出 u,t,要求回答在时刻 t,点 u 上有多少人。

输入格式

第一行两个整数 n,m 表示点数和边数。

接下来 m 行每行三个整数 u,v,w,表示 u,v 之间有一条边权为 w 的边。

接下来一行一个整数 Q 表示询问数。

最后 Q 行每行两个整数 u,t 表示一组询问。

输出格式

Q 行每行一个整数表示答案。

样例输入 1

7 8
1 2 5
1 4 3
1 5 6
2 3 7
3 5 8
6 4 10
7 6 5
5 7 1
2
3 8
1 1

样例输出 1

3
0

*数据规模

  • 对于30%的数据,n,m,Q,t500
  • 另有30%的数据,n,m,Q,t5000
  • 对于100%的数据,n,m,Q1060t,w109。无重边自环。

本题 IO 量较大,请视情况斟酌 IO 方式。

Sol

暴力模拟可以拿到 30pts,时间复杂度 O(Qnt) .

一个点走 k 步到了点 u 就把 ansk,uansk,u+1,时间复杂度 O(nt+Q),可以获得 60pts .

把每条有向边看成一个点,这样每个点的出边是唯一确定的。
并且原图中之后最大边和次大边有可能走到,所以这张新图的点数只有 2n
这样连出的新图是一个环套内向树森林。
最后询问的时候一个询问被拆成新图上两个点上的询问。
不妨把边反向,变成询问一个点 ut 步能走到多少不同的黑点(其中黑点是那些最大边对应的点)。

不妨把询问离线。

如果 u 不在环上,那么就是询问子树中深度为的黑点有多少个。那么直接做可以启发式合并数组,复杂度 O(nlogn)
其实每次对于当前点,它直接复用了长儿子的数组。然后所有短儿子的数组被暴力合并到这个数组里。这个复杂度其实是所有短儿子子树深度的总和。注意到短儿子其实就是一条长链的顶端,这就是所有长链长度的总和。所以复杂度其实是 O(n) 的。

或者可以再把一个询问拆成两个分别挂在 dfs 序的左右端点。然后再离线一次询问,把 dfs 序做一个前缀和(从前往后扫,维护当前前缀对应的所有点中,深度为的有多少个,这是一个数组)。然后在左端点把答案减去,右端点加上。复杂度 O(n)

如果 u 在环上,假设环长是 L,那么一个 t 步能走到的点,t+L 步也一定能走到。不妨随便固定环上的一个点作为起点,把环拆成链。然后处理出距离它长度为 k 的点一共有 ak 个(简单路径)。

那么对于询问就是要回答数组 a 下标模 L 的前缀和。这个预处理一下前缀和可以 O(1) 回答。

然后对于不同的询问 u,还要求出它们分别作为起点时,这个数组 a 是什么。

不妨令环上的下一个点是 v。假设已经求出了 u 对应的数组,现在要求 v 对应的数组。

这一步其实就是消除掉子树的贡献,然后把的 u 子树移到环最后(相当于深度 +L)。最后再把所有点的距离都 1

不妨把深度按照模 L 进行分类,那么每个类互不相关(因为做前缀和不会跨类)。
因为现在要维护一个前缀和的数组,所以每次修改要对后缀进行加减。这个可以用树状数组来维护。复杂度 O(nlogn)

但是注意到每次的修改是把距离 +L。换言之,在同一个类中,这些深度对应的位置只往后移了一格。
从而如果修改 k 个位置,前缀和只会至多修改 k+1 个位置。所以暴力修改这些位置,复杂度 O(n)

故总复杂度是线性的。

2. 算法 - 贪心 & 数学

1. 贪心

Problem 1:有 n 个农民,每个有 ai 单位的牛奶,单价 Pi。现在要求从农民手里购买不超过 ai 单位的牛奶。总共买 M 单位。求最小花费。

排个序就好了。


Problem 2:有 n 个物品,每个有大小。有若干容积为 L 的箱子,在每个里面至多放两个物品。问装下所有物品至少要多少箱子。

排序,最大最小配对。

正确性证明:

设序列中最大值为 A,如果其和最小的 B 不能放一起,那么显然它只能自己放一个箱子。

那如果可以放,那么最优解中 A 落单。
如果 B 也落单了:矛盾

若有令一个 C 使得 BC 配对:换成 A,B 配对,C 落单,显然更优。

AC 配对了:
B 落单了:则让 A,B 配对,C 落单,更优。

BD 配对:那么让 A,B 配对,C,D 配对更优。

所有情况都使得 A,B 配对,Q.E.D.


Problem 3:有 n 个物品,每个物品有属性 A,B。将其排成一行。
i 物品放在 j 位置将会产生 (j1)Ai+(nj)Bi 的代价,使总代价最小。

先把式子变成 total cost=CONSTANT+sum(aibi),其中 CONSTANT 是一个常量。

过程:

(j1)Ai+(nj)Bi=j(aibi)ai+nbi

显然后面是个常量,故 total cost=CONSTANT+sum(aibi)

aibi 排序即可。


?????????:求 MST(最小生成树) .

性质:一个点的最小出边一定在 MST 中。

证明:

假设 x 最短的一条边为 (x,y) .
那么我们现在考虑将 x,y 连接起来(最小生成树的任意两点一定是连通的嘛),那么就只有两种不同的情况,直接连通和间接连通。

我们现在就是要证明直接连通至少不比间接连通差。
既然要间接连通,那么假设这条路是 xaby,其实这个最终连接的效果是可以等效于 abyx 的,
然而这里唯一的区别就是一个选择了了 xa,一个选择了 yx,那么我们知道选择 (x,y) 的代价肯定是不差于 (x,a)的。

证毕。

替换原则:最小生成树一定是最小瓶颈生成树。

证明:

显然

Algorithm 1:Prim 算法

思想:先随便找一个点 u,寻找 u 的最小出边对应的点 v,然后寻找 u,v 的最小出边对应的点 wwv),,一直操作直到所有点都被找到。

维护 disu 表示目前点 u 的最小边权,每次寻找最小的 dis 然后更新出边即可。

证明:

由于 MST 的性质,所以全局最小边也在 MST 中。
这就把 Prim 的核心思想证明了。
Q.E.D.

时间复杂度:

Fibonacci 堆 普通堆
稀疏图 O(nlogn+m) O(mlogn)
稠密图 O(n2) O(n2logn)

Algorithm 2:Kruskal 算法

思想:先把边从小到大排序,用并查集维护,每次把不形成环且边权最小的边的两个点并起来,最后得到的就是 MST。

证明:

考虑最小瓶颈生成树的做法
二分一个 k,判断瓶颈 k 的最小瓶颈生成树是否存在。

判断可以用并查集合并,但是发现可以直接枚举合并,这和 Kruskal 的算法过程一模一样。
因为最小生成树一定是最小瓶颈生成树,故 Kruskal 求出的一定是 MST。

Q.E.D.

时间复杂度:(若并查集用按秩合并 + 路径压缩)O(mlogm+mα(n))

Algorithm 3:Boruvka 算法

思想:把每条边都连出最小边,然后直接把联通块缩成点,反复操作即可。

证明:

显然

时间复杂度:O(mlogm)

Algorithm 4:???算法

先跑 O(loglogn) 次 Boruvka:O(mloglogn)

得到 O(nlogn)个点的图。再用 Prim。

时间复杂度 O(n+m)

2. 数学

2.1 初等数论

约数:定义,对于两个整数 a,d,若存在一个整数 k,使得 a=kd,则称 da 的约数(因数),ad 的倍数,记做 da .

一个数的约数个数是 O(n) 的,但是 1n 中每个数的正约数个数和是 O(nlogn) 的:

i=1nni=O(nlogn)

因为调和级数 H(n)=i=1n1i=logn+γ,乘上个 n 也就是 O(nlogn) 的了。

质数:定义,对于 n>1,如果其正约数只有 1n,则称 n 为素数(质数),其余除 1 外都是合数。

素数定理:n 以内的素数个数为 π(n)nlogn .

筛法:

这个思想就是用约数筛掉,时间复杂度 O(nloglogn)

当然还有 O(n) 的线性筛,但普及组不做要求。

判断素数:

  1. O(n) 直接做
  2. 先做出 isprime 素数表,就能 O(nloglogn) 预处理,O(nlogn) 查询了。
  3. Miller - Rabin 算法,因为太强,不做要求。
  4. AKS 算法,因为太强,不做要求(多项式时间的确定性算法!)。

算术基本定理:对于任意一个正整数 n,有且仅有一种方法将 n 表示为如下形式:

n=p1q1p2q2prqr

其中,pi 是满足 p1<p2<<pr 的素数,qi 为正整数。

分解质因数:

就是朴素的枚举法分解质因数,时间复杂度 O(n)(其实可以再优化下)。

还有 Pollard Rho 算法,因为太强,所以不做要求(时间复杂度 O(n4)

最大公约数与最小公倍数:最大的公约数叫最大公约数,记做 gcd(a,b);最小的公倍数叫最小公倍数,记做 lcm(a,b) .

性质:

  • ab=gcd(a,b)lcm(a,b)
  • gcd(a,b)=gcd(b,amodb)(辗转相除法)
  • gcd(a,b)=gcd(a+kb,b)(kZ)
  • gcd(ka,kb)=kgcd(a,b)
  • gcd(a1,a2,,an)=gcd(a1,a2a1,a3a2,,anan1)(更相减损术)
  • a=C1p1e1p2e2prerb=C2p1f1p2f2prfr(其中 C1/2 后面的东西是标准分解,C1/2 是随便一个常数),则:
    • gcd(a,b)=p1min(e1,f1)p2min(e2,f2)prmin(er,fr)
    • lcm(a,b)=C1C2p1max(e1,f1)p2max(e2,f2)prmax(er,fr)

因为 gcd(a,b)=gcd(b,amodb),所以可以得到如下求 gcd 的程序(辗转相除法):

更相减损术:

也是 O(logn) 的,但是只用了乘法和加法,适合高精。

裴蜀定理:对于不全为 0 的非负整数 a,b,必然存在整数 x,y,使得

ax+by=gcd(a,b)

方程 ax+by=c 有解的充要条件为 gcd(a,b)c .

欧几里得算法:

ax+by=gcd(a,b)(abb+amodb)+by=gcd(b,amodb)b(abx+y)+(amodb)x=gcd(b,amodb)

即可求出一组满足上式的解 {x=abx+yy=x .

原方程的一组特解 {x0=yy0abx0 .

所有解为 {x=x0+kbgcd(a,b)y=y0kbgcd(a,b) .

当方程为 ax+by=d 时,原方程的解为

{x=dx0+kbgcd(a,b)y=dy0kbgcd(a,b)

代码:

求线性同余方程 axb(modp),或判断其无解。

显然这个等同于求解 axpy=b,套 exgcd 即可。有解条件就是 gcd(a,p)b

p 为素数时,我们有费马小定理:

对于任意整数 a 和素数 p,有:

apa(modp)

所以答案为 bap2 .
b=1 时,这东西又叫做 ap 的乘法逆元。

O(n)1n 内的逆元:

先用费马小定理求出 n!1 .

利用 k1(k+1)1(k+1)(modp) 倒推出所有阶乘的逆元。

利用等式 k1=k!1(k1)! 求出所有数的逆元。

2.2 组合数学

加法原理:若一个事件可以分为两类,这两类的方案数分别为 a,b,则这个事件的方案数为 a+b .
乘法原理:若一个事件可以分为两步,这两步的方案数分别为 a,b,则这个事件的方案数为 a×b .

排列数:有 n 个不同的物品,从中有序的选出 m 个物品,这个方案数记做 Anm(或 Pnm).

Anm=n(n1)(n2)(nm+1)=n!(nm)!

组合数:有 n 个不同的物品,从中无序地选出 m 个物品,
这个方案数记为 Cnm (或 (nm))。

Cnm=n(n1)(n2)(nm+1)123m=n!m!(nm)!

可重全排列:有 k 种物品,物品的总个数为 n,每种物品的
个数分别为 n1,n2,,nk 个,它们组成的全排列个数为

Cnn1Cnn1n2Cnn1n2n3Cnknk=n!n1!n2!nk!

  • Anm=Cnmm!
  • Cnm=Cnnm
  • Cnm=Cn1m+Cn1m1
  • i=0nCni=2n

可重组合:有 n 种物品,从中无序地选出 m 个,同种物品可以选出多次,方案数为 Cn+m1m .

隔板法:

不定方程 x1+x2++xm=n 的正整数解的个数为 Cn1m1 .
不定方程 x1+x2++xm=n 的非负整数解的个数为 Cn+m1n1 .

Catalan 数:

  • 通项:Cn=1n+1(2nn)
  • 递推:

Cn=i=0n1CiCni1

Cn=4n2n+1Cn1

二项式定理:

(x+y)n=i=0n(ni)xiyni

求组合数 Cnm,结果 modp .

  1. 直接用递推式,时间复杂度 O(n2) .
  2. 利用公式 Cnm=n!m!(nm)!,将 n,m,nm 分解素因子,时间复杂度 O(π(max{n,m})) .
  3. 还是利用方法二中的公式,但把后面分解质因数的部分修改为:预处理 i! 及其逆元。
    时间复杂度 O(n)。但有要求:p>n,且 i! 存在对
    p 的逆元。这种方法常用于 p 为大质数时。
  4. Lucas 定理,对于任意素数适用,但不作要求。

容斥原理:

|S1S2Sn|=i|Si|i<j|SiSj|+i<j<k|SiSjSk|++(1)n1|S1S2Sn|

|S1¯S2¯Sn¯|=|U||S1S2Sn|

特殊情况:

  1. |AB|=|A|+|B||AB|
  2. |ABC|=|A|+|B|+|C||AB||BC||CA|+|ABC|

2.3 线性代数

矩阵:
定义:一个 n×m 的二维数组:

An×m=[a11a12a1ma21a22a2man1an2anm]

运算:

  • 加减法:C=A+BCij=Aij+Bij,满足交换律和结合律。
  • 数乘:C=λACij=λAij,满足对加减法的分配律。
  • 乘法:对于一个 n×r 的矩阵 A 和一个 r×m 的矩阵 B,其乘积为一个 n×m 的矩阵 C=AB,其中:

Cij=k=1rAikBkj

因为矩阵乘法满足结合律,所以矩阵求幂可以用快速幂。

矩阵加速:求 Fibonacci 数列的第 nFnn1018 .

构造一个 1×2 的矩阵表示 Fibonacci 数列的相邻两项:

[Fn,Fn1]

可以发现:

[Fn+1,Fn]=[Fn,Fn1][1110]

显然初始矩阵是 [1,0],跑个矩阵快速幂即可。

高斯消元法:

求解下列 n 元线性方程组的解,或判断其无解或无穷多解:

{a11x1+a12x2++a1nxn=b1a21x1+a22x2++a2nxn=b1am1x1+am2x2++amnxn=bm

消成斜线即可。

2.4 简单几何

向量:有向线段。
坐标表示:用平面中的点对 (x,y) 表示,此时向量的长度为
(x,y) 到原点的距离,方向为点 (x,y) 相对于原点的方向。

  • 加减法:(x1,y1)+(x2,y2)=(x1+y1,x2+y2) .
    几何意义:点的平移
  • 数乘:λ(x,y)=(λx,λy) .
    几何意义:长度变为原来的 λ 倍。
  • 点积(数量积或内积):(x1,y1)(x2,y2)=x1x2+y1y2 .
    几何意义:一个向量的长度乘以另一个向量在它上面的投影的长度。
  • 叉积(向量积):(x1,y1)×(x2,y2)=x1y2x2y1 .
    几何意义:它们组成的平行四边形的有向面积。

正弦定理:对于 ABC 的三边长 a,b,c 及其对角 ABC,有:

asinA=bsinB=csinC

余弦定理:对于 ABC 的三边长 a,b,c 及其对角 ABC,有:

c2=a2+b22abcosC

b2=a2+c22accosC

a2=b2+c22bccosC

旋转公式:对于平面中的一个点 (x,y),将其绕原点逆时针旋转角 θ,得到的新点坐标为

(x,y)=(xcosθysinθ,xsinθ+ycosθ)

posted @   yspm  阅读(167)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
😅​
点击右上角即可分享
微信分享提示