贺题记录(数学+图论+dp+树型问题)
作者:互联网
数论水习
题单位置:洛谷.数论
1.P1965转圈游戏
solution:思路十分简单答案就是$x+m*10^kMOD (n) $,快速幂练手题
(Done)
2.P5431乘法逆元2
solution:一道在线转离线的题目,设$s_i=\prod_{i=1}^na_i
,
那
么
很
容
易
知
道
,那么很容易知道
,那么很容易知道\frac{1}{a_i}=s_i-_1*\frac{1}{s_i}$,那么就可以线性求逆元了
(Done)
3.P2613有理数取余
solution:对于求 a b ≡ x ( m o d p ) \frac{a}{b}\equiv x\pmod{p} ba≡x(modp)的x,我们可以进行一些小的转化:
1.上式可以转化为$a\equiv bx\pmod{p} $
2.然后对于上面的式子还可以进一步转化为: b x 1 ≡ 1 ( m o d p ) bx_1\equiv 1\pmod{p} bx1≡1(modp),其中 x 1 x_1 x1=x/a
于是我们可以通过 e x g c d exgcd exgcd求出 x 1 x_1 x1,然后答案就是 x 1 ∗ a x_1*a x1∗a了
然后,还需要对于无解情况的分析,即当 b ≡ 0 ( m o d p ) b\equiv 0\pmod{p} b≡0(modp)时
4.P1082同余方程
solution:问题可以转化为 a x + b y = 1 ax+by=1 ax+by=1其中b为膜数,于是就是一个裸的扩欧了
5.P5656二元一次方程
solution:扩欧板子了属于是,但是需要补充的是对于有解的不定方程的解的个数以及最大最小值
首先是解的个数,如果我们得到了一组二元解$(x,y) $,那么我们可以通过加或减去[gugugu]
6.私题(I’m)
把所有武器变为同一个武器,那么这个武器造成伤害的概率就是P= ∑ i = 1 n p i n \frac{\sum\limits_{i=1}^np_i}{n} ni=1∑npi,然后根据概率枚举双方收到的伤害,并进行计算。
最后答案为:
∑
i
=
1
A
∑
j
=
1
B
[
i
<
j
]
(
A
i
)
P
i
(
1
−
P
)
A
−
i
(
B
j
)
P
j
(
1
−
P
)
B
−
j
\sum\limits_{i=1}^A\sum\limits_{j=1}^B[i<j]\dbinom{A}{i}P^i(1-P)^{A-i}\dbinom{B}{j}P^j(1-P)^{B-j}
i=1∑Aj=1∑B[i<j](iA)Pi(1−P)A−i(jB)Pj(1−P)B−j
需要通过前缀和以及
L
u
c
a
s
Lucas
Lucas定理进行优化
又因为B十分的大,我们可以考虑容斥,计算A小于B的情况,那么我们只需要枚举A即可,然后需要求出
(
1
−
p
)
B
(1-p)^B
(1−p)B,而b算比较大的数,所以我们要根据扩展欧拉定理进行取模,详细见下面
(Done)
7.CF559C Gerald and Giant Chess
solution:
一道组合递推题,老师考过一道类似的题目,首先我们要知道一个知识:一个 n ∗ m n*m n∗m的矩形中,我们想要从 ( 0 , 0 ) 到 达 ( n , m ) (0,0)到达(n,m) (0,0)到达(n,m)(只允许向上或者向右),我们有 ( n n + m ) \dbinom{n}{n+m} (n+mn)种方案,,同理,从 ( x 1 , y 1 ) 到 ( x 2 , y 2 ) (x_1,y_1)到(x_2,y_2) (x1,y1)到(x2,y2)的方案数为 ( x 2 − x 1 x 2 − x 1 + y 2 − y 1 ) \dbinom{x_2-x_1}{x_2-x_1+y_2-y_1} (x2−x1+y2−y1x2−x1)
于是对于本题,我们设 f i f_i fi表示到第i个黑棋的方案数,我们把最后的目的地当做一个黑棋,根据乘法原理以及减法原理可以知道 f i f_i fi= ( x i − 1 x i + y i − 2 ) − ∑ j = 0 i − 1 f j ∗ ( x i − x j x i − x j + y i − y j ) \dbinom{x_i-1}{x_i+y_i-2}-\sum\limits_{j=0}^{i-1}{f_j*\dbinom{x_i-x_j}{x_i-x_j+y_i-y_j}} (xi+yi−2xi−1)−j=0∑i−1fj∗(xi−xj+yi−yjxi−xj)最后答案就是 f n + 1 f_{n+1} fn+1
8.P5091扩展欧拉定理
solution:
根据欧拉定理我们知道在a与b互质的时候有
a
p
h
i
b
≡
1
(
m
o
d
b
)
a^{phi_b}\equiv1\pmod{b}
aphib≡1(modb)
其中phi为欧拉函数于是设
b
m
o
d
k
=
t
b\bmod k=t
bmodk=t
那么有
b = s ∗ k + t b=s*k+t b=s∗k+t
然后又根据欧拉定理,那么就可以得到 a b ≡ a b m o d ϕ ( k ) ( m o d k ) a^b\equiv a^{b\bmod \phi(k)}\pmod{k} ab≡abmodϕ(k)(modk)
而扩展欧拉定理是用来处理a,b不互质的情况,不考虑证明直接上结论: a b ≡ a ( b m o d ϕ ( m ) ) + ϕ ( m ) ( m o d m ) a^b\equiv{a^{(b\bmod \phi(m))+\phi(m)}}\pmod{m} ab≡a(bmodϕ(m))+ϕ(m)(modm)但是需要特判一下b小于 ϕ ( m ) \phi(m) ϕ(m)的时候是无解的
对于欧拉函数phi的求解见链接
(Done)
9.P2421 荒岛野人
solution:
其实就是找最小的M,使得对于任意i,j,同余方程:
C i + x ∗ P i ≡ C j + x ∗ P j ( m o d M ) C_i+x*P_i\equiv C_j+x*P_j\pmod{M} Ci+x∗Pi≡Cj+x∗Pj(modM)无解,x> m i n ( L i , L j ) min(L_i,L_j) min(Li,Lj),一共有 n 2 n^2 n2个如是同余方程,化为二元一次方程,根据 e x g c d exgcd exgcd断无解。需要枚举M
tips:化为二元一次方程为
x
∗
(
P
i
−
P
j
)
+
y
∗
M
=
C
j
−
C
i
x*(P_i-P_j)+y*M=C_j-C_i
x∗(Pi−Pj)+y∗M=Cj−Ci
[Done]
10.P2155 沙拉公主的疑惑
solution:
根据欧几里得公式可以知道
g
c
d
(
a
,
b
)
=
g
c
d
(
a
+
b
∗
k
,
b
)
gcd(a,b)=gcd(a+b*k,b)
gcd(a,b)=gcd(a+b∗k,b),所以我们把
N
!
N!
N!分为
k
=
N
!
M
!
k=\frac {N!}{M!}
k=M!N!段,如果我们在一段中找到了一个与
M
!
M!
M!互质的数,那么这k段中,每一段都可以找到一个于是答案就是
k
∗
ϕ
(
m
!
)
k*\phi(m!)
k∗ϕ(m!)
[Done]
11.P4139 上帝与集合的正确用法
solution:
我们可以采取扩展欧拉公式进行降幂,我们知道$a^b \equiv a^{b\bmod \phi§+\phi§}\pmod p $,于是我们可以直接递归下去求解就可以了
[Done]
tips:欧拉函数肯定用欧拉筛啦,就是在欧拉线性筛质数的时候筛见code
12.P2398 GCD SUM
solution:
先看个有趣的资料叫做欧拉反演
根据以上知识我们知道 g c d ( i , j ) = ∑ d ∣ g c d ( i , j ) ϕ ( d ) gcd(i,j)=\sum\limits_{d|gcd(i,j)}\phi(d) gcd(i,j)=d∣gcd(i,j)∑ϕ(d),也等价于 ∑ d ∣ i , j ϕ ( d ) \sum \limits_{d|i,j}\phi(d) d∣i,j∑ϕ(d),于是最后我们可以枚举d,然后看n中有多少个i,j满足 d ∣ i , j d|i,j d∣i,j,也就是 n i ∗ n i \frac{n}{i}*\frac{n}{i} in∗in个,于是 a n s = ∑ d = 1 n ϕ ( d ) ∗ n i 2 ans=\sum\limits_{d=1}^{n}\phi(d)*\frac{n}{i}^2 ans=d=1∑nϕ(d)∗in2
为巩固知识进行下简单证明:
我们构造函数
f
(
n
)
=
∑
d
∣
n
p
h
i
d
f(n)=\sum\limits_{d|n}phi_d
f(n)=d∣n∑phid,那么
f
(
n
m
)
=
∑
d
∣
n
m
ϕ
(
d
)
=
∑
d
∣
n
ϕ
(
d
)
∗
∑
d
∣
m
ϕ
(
d
)
=
f
(
n
)
∗
f
(
m
)
f(nm)=\sum\limits_{d|nm}\phi(d)=\sum\limits_{d|n}\phi(d)*\sum\limits_{d|m}\phi(d)=f(n)*f(m)
f(nm)=d∣nm∑ϕ(d)=d∣n∑ϕ(d)∗d∣m∑ϕ(d)=f(n)∗f(m),于是我们构造出来的函数是积性函数,那么对于
n
n
n的每一个质因子
f
(
p
c
)
=
ϕ
(
1
)
+
∑
i
=
1
c
ϕ
(
p
)
i
f(p^c)=\phi(1)+\sum\limits_{i=1}^{c} \phi(p)^i
f(pc)=ϕ(1)+i=1∑cϕ(p)i
tips:
ϕ
(
p
2
)
=
p
∗
(
p
−
1
)
\phi(p^2)=p*(p-1)
ϕ(p2)=p∗(p−1)
于是:
f
(
p
c
)
=
ϕ
(
1
)
+
ϕ
(
p
)
+
…
…
+
ϕ
(
p
c
)
=
1
+
(
p
−
1
)
+
p
∗
(
p
−
1
)
+
(
p
2
−
p
)
+
…
…
+
(
p
k
−
p
k
−
1
)
f(p^c)=\phi(1)+\phi(p)+……+\phi(p^c)=1+(p-1)+p*(p-1)+(p^2-p)+……+(p^k-p^{k-1})
f(pc)=ϕ(1)+ϕ(p)+……+ϕ(pc)=1+(p−1)+p∗(p−1)+(p2−p)+……+(pk−pk−1)为等差数列+1,于是得到
f
(
p
c
)
=
p
c
f(p^c)=p^c
f(pc)=pc,再根据算法基本定理便可得证
13.#21252. 「NOIP2021 国庆集训 B 组 Day1」逛动物园
solution:
这是一个树的结构证明见后面
原来每个位置肯定是有 3 n 3^n 3n种情况我们考虑每次一操作后的变化
1.u>v u胜利 P ( A ) = 1 3 P(A)=\frac{1}{3} P(A)=31
2.u==v u胜利 P ( B ) = 1 3 P(B)=\frac{1}{3} P(B)=31
3.v>u v胜利 P ( C ) = 1 3 P(C)=\frac{1}{3} P(C)=31
综上 发现每次操作过后u存活的概率为 P ( u ) = 2 3 P(u)=\frac{2}{3} P(u)=32,而v为 1 3 \frac{1}{3} 31,意思是u的方案数为 s u ∗ 2 3 s_u*\frac{2}{3} su∗32,v的方案数为 s v ∗ 1 3 s_v*\frac{1}{3} sv∗31
有了这个思路就好办了,我们设u存活下来的概率为 h x h_x hx,那么对于操作二,ans= h u ∗ 3 n h_u*3^n hu∗3n,而每次操作1的话,就要在v的子树中的每个节点 h x ∗ 1 3 h_x*\frac{1}{3} hx∗31,u则是子树内节点的 h x ∗ 2 3 h_x*\frac{2}{3} hx∗32(因为最后他们会和v打,胜率为 2 3 \frac{2}{3} 32,v同理)然后就是线段树维护甚至不需要树链剖分了
树形结构证明:我们设 f a v = u fa_v=u fav=u,又因为无论输赢最后u节点还是会在,并且以后u进行操作也会对u,v的权值造成影响,所以得证可以为树形结构
14.「NOIP2021 国庆集训 B 组 Day2」#子集问题
sol:看来复习数学多少还是有点用。
我们考虑当 n = = 4 n==4 n==4到 n = = 5 n==5 n==5的过程中怎样转变的。根据手模拟,可以知道
当 n = = 4 n==4 n==4时,方案为: ( 1 , 3 ) , ( 1 , 4 ) , ( 2 , 4 ) (1,3),(1,4),(2,4) (1,3),(1,4),(2,4)
当 n = = 5 n==5 n==5时,方案为: ( 1 , 3 ) , ( 1 , 4 ) , ( 2 , 4 ) , ( 1 , 5 ) , ( 2 , 5 ) , ( 1 , 3 , 5 ) , ( 3 , 5 ) (1,3),(1,4),(2,4),(1,5),(2,5),(1,3,5),(3,5) (1,3),(1,4),(2,4),(1,5),(2,5),(1,3,5),(3,5)
然后发现多出来的部分全是与5有关的,而多出来的(1,3,5)去掉5正是 n = = 3 n==3 n==3时唯一的方案数(1,3),而其他的都是诸如: ( 1 , 5 ) … … ( 5 − 2 , 5 ) (1,5)……(5-2,5) (1,5)……(5−2,5)一共n-2个,然后多弄几个就发现了递推式: f n = f n − 1 + ( f n − 2 + n − 2 ) f_n=f_n-1+(f_{n-2}+n-2) fn=fn−1+(fn−2+n−2),然后可以通过矩阵加速优化(考场上不会裂开)
15.冒泡排序
找规律的题目,如果你知道这个结论的话,其实很简单,不然只能像我一样暴力枚举找规律了qwq
f [ a ] = f [ a − 1 ] ∗ a + ( n − 1 ) ∗ ( n − 1 ) ! f[a]=f[a-1]*a+(n-1)*(n-1)! f[a]=f[a−1]∗a+(n−1)∗(n−1)!
为什么呢?考虑 n = 2 n=2 n=2,和 n = 3 n=3 n=3两种情况
n=2时 n=3时
1 2 cnt=0 1 2 3 cnt=0 1 3 2 cnt=1
2 1 cnt=1 2 1 3 cnt=1 2 3 1 cnt=2
f[2]=1 3 1 2 cnt=2 3 2 1 cnt=1
f[3]=7
然后你就发现两个东西
1.原来的 ( n − 1 ) ! (n-1)! (n−1)!种情况每个都加上一个新的n,每种有n个位置可以放,但是在原来基础上产生贡献的只有 n − 1 n-1 n−1个,故加上 ( n − 1 ) ∗ ( n − 1 ) ! (n-1)*(n-1)! (n−1)∗(n−1)!
2. n ∗ ( f [ n − 1 ] ) n*(f[n-1]) n∗(f[n−1])是因为你减去我们先前发现的这个后,就可以发现这个规律(逃),正经来讲就是你发现我们上面只算了n插进去带来的新贡献,还有原来的没算,意思是原来有 ( n − 1 ) ! (n-1)! (n−1)!种方式,然后你变成了 n n n而此时方案数就成了 n ! n! n!,变成了以后就肯定要乘上一个 n n n,因为你n!个方案肯定是原来的基础上加上一个n形成的
所以说数学分析配上合适的打表是个不错的选择,其实你可以上网站搞
16.P2158仪仗队
solution:
本题有两种解法
s o l 1 : sol_1: sol1:考虑容斥:根据画图发现,不能
17.「NOIP2021 国庆集训 B 组 Day6」#循环卷积
solution:
发现性质对于卷积的表达 c i = max 0 ≤ j < n ( a j + b i − j + n m o d n ) c_i=\max_{0\leq j<n}({a_j+b_{i-j+n\bmod n}}) ci=max0≤j<n(aj+bi−j+nmodn),然后把a,b的下标作和,就有神奇的东西 j + i − j + n m o d n = i j+i-j+n\bmod n=i j+i−j+nmodn=i,然后发现, c i > = max ( max a i max b i ) c_i>=\max(\max{a_i}\max{b_i}) ci>=max(maxaimaxbi),且当符合条件的 a i , b j a_i,b_j ai,bj中有一个为0时取等号。然后统计出 a , b a,b a,b中大于0的个数,暴力枚举计算答案即可
18.「NOIP2021 国庆集训 B 组 Day9」#排列计数
sol:
我们很快知道递推式子: f [ n ] = f [ n − 1 ] + f [ n − 3 ] + 1 f[n] = f[n-1]+f[n-3]+1 f[n]=f[n−1]+f[n−3]+1,然后我们矩阵,矩阵为
1 0 1 1
1 0 0 0
0 1 0 0
0 0 0 1
但是T很大,我们还需要继续优化,我们知道
a
p
=
a
p
∗
p
p
∗
a
p
m
o
d
p
a^p=a^{\sqrt p*\frac{p}{\sqrt p}}*a^{p\bmod \sqrt p}
ap=ap
∗p
p∗apmodp
,可以预处理出矩阵即可
code
19.P4476 数字统计
sol:
真是一个毒瘤题。首先观察两组数据
m = 3 m = 4
0 000 0 0000 1
1 001 1 0001 0
2 010 0 0010 1
3 011 0 0011 1
4 100 1 0100 0
5 101 1 0101 0
6 110 1 0110 0
7 111 1 0111 0
然后得到傻子都看得出的规律,设从左往右扫到的第一个1后面的长度为len,如果当len与m同奇偶性时,这个数的贡献为1,而这样数恰好在一块,自然放在一起并且满足块大小为 2 k 2^k 2k的规律,所以以 2 k 2^k 2k为一块,如果同奇偶就加上(r-l+1),这里说的是计算1的贡献,如果为0就容斥,于是就很容易得到答案了,只要加上高精度就可以过了
20.P4478 上学路线
sol:
同CF559C,移步上方,需要特殊处理一下模数不为质数与n,m很大的情况。如果m,n很大就不能预处理jc,njc了,而是采用Lucas定理计算小模数的组合数;如果模数不为质数,则考虑通过对大质数进行质因数分解,构造同余方程,CAT合并求解
21.雅礼联考 二次剩余
sol:
因为当m很大的时候
f
(
x
)
=
(
x
−
m
)
2
+
k
<
=
t
f(x) = (x-m)^2+k<=t
f(x)=(x−m)2+k<=t等价于
f
(
x
)
=
(
x
−
m
)
2
<
=
t
f(x)=(x-m)^2<=t
f(x)=(x−m)2<=t,也就是说我们可能不合法的函数满足
x
−
t
<
=
m
<
=
t
+
x
x-\sqrt t<=m<=\sqrt t+x
x−t
<=m<=t
+x,所以对每个m都维护一个以k为关键字的小根堆,每次弹出的范围就是上面的。
code
22.雅礼联考 飞翔的鸟
sol:
根据题意可以构造出两个矩阵A,B分别表示无/有障碍到每一列的方案数
以k = 5为例子:
[1 1 0 0 0 [0 0 0 0 0
1 1 1 0 0 0 0 1 0 0
A= 0 1 1 1 0 B = 0 0 1 0 0
0 0 1 1 1 0 0 1 0 0
0 0 0 1 1 ] 0 0 0 0 0]
那么我只需要枚举柱子在的位置i,就可以得到答案:
a
n
s
=
∑
i
=
2
i
<
=
n
−
1
A
i
−
1
∗
B
∗
A
n
−
i
ans=\sum_{i = 2}^{i<=n-1}A^i-1*B*A^{n-i}
ans=∑i=2i<=n−1Ai−1∗B∗An−i,答案就是
a
n
s
[
k
2
]
[
k
2
]
ans[\frac{k}{2}][\frac{k}{2}]
ans[2k][2k]乘上2的逆元
code
23.CF1427E XUM
sol:
严格来讲这是一道思维构造的好题
考虑不断化繁为简,去掉最高位。
例如给的数是X,以X = 7为例子
000111 + 000111 = 001110
001110 + 001110 = 011100
011100 ^ 000111 = 011011
011011 + 011100 = 110111
110111 ^ 000111 = 110000
110000 ^ 111000 = 001000
011100 ^ 001000 = 010100
010100 ^ 010000 = 000100
000100 ^ 000111 = 000011
这样就变成了X = 3的子问题
同样的处理即可,简单讲一下处理方法:
我们需要找到的最高位,可以将X向左移到最低位和最高位匹配,然后两数异或起来,这样最高位就是0了令这个数位z,再将z+y记为p,px得到q,再将y左移一位得到h,然后hq就可以得到
2
h
i
g
h
x
+
1
2^{high_x+1}
2highx+1再用这个把y中大于
2
h
i
g
h
2^{high}
2high的数全部异或掉即可
24.UVA12716 GCD等于XOR GCD XOR
sol:
一道很有思维的数学题,考虑到xor操作实际上为不进位加法所以 a − b < = a x o r b < = a + b a-b<=a xor b<=a+b a−b<=axorb<=a+b,又因为 g c d ( a , b ) < = a − b gcd(a,b)<=a-b gcd(a,b)<=a−b证明很简单:设 g c d ( a , b ) = c , a = c ∗ k 1 , b = c ∗ k 2 , a − b = ( k 1 − k 2 ) ∗ c > = c gcd(a,b)=c,a=c*k_1,b=c*k_2,a-b=(k_1-k_2)*c>=c gcd(a,b)=c,a=c∗k1,b=c∗k2,a−b=(k1−k2)∗c>=c,那么若要满足异或和gcd相等必有 g c d ( a , b ) = a x o r b = a − b gcd(a,b)=axorb=a-b gcd(a,b)=axorb=a−b,于是暴力枚举即可
25.SP8547 MAIN74 - Euclids algorithm revisited
sol:
我们知道更相减损数即 g c d ( a , b ) = g c d ( b , a − b ) gcd(a,b)=gcd(b,a-b) gcd(a,b)=gcd(b,a−b), g c d ( f k , f k − 1 ) = g c d ( f k − 1 , f k − f k − 1 ) = … … = g c d ( f 2 , f 1 ) = 1 gcd(f_k,f_{k-1})=gcd(f_{k-1},f_{k}-f_{k-1})=……=gcd(f_2,f_1)=1 gcd(fk,fk−1)=gcd(fk−1,fk−fk−1)=……=gcd(f2,f1)=1,然后就不难发现是个斐波拉契数列了
26.等差数列
sol:
一道很有意思的分类讨论数学题,我们分 2 ∗ N < M 2*N<M 2∗N<M,和 M ≤ 2 ∗ N M\le 2*N M≤2∗N两种情况来讨论:
首先对原序列排序,任意找两个数,相减得到 K ∗ D K*D K∗D(等差数列)
1. 2 ∗ N ≤ M 2*N\le M 2∗N≤M时,那么为了满足等差数列的性质,那么应该有K个数因为模mod的原因没有出现在A序列中,于是可以算出这个K,求出D,进一步求出这个开头
2. M < 2 ∗ N M<2*N M<2∗N时,此时就有可能出现中间K个都在这个序列中的情况了,我们可以求出 m o d m o d \bmod mod modmod情况下A的补集,他仍然为公差为d的等差序列,但是长度小于M/2,所以可以按照上面的方法求出答案
dp贺题
题单
1.CF734E Anton and Tree
solution:
对于一条边 ( u , v ) (u,v) (u,v)如果 c o l u = c o l v col_u=col_v colu=colv那么 e i . w = 0 e_i.w=0 ei.w=0,否则边权为1,最后求树的直径 d d d, a n s = [ d + 1 ] / 2 ans=[d+1]/2 ans=[d+1]/2
对于树的直径(dp法):
a n s = m a x ( a n s , d i s u + d i s v + w ) ans=max(ans,dis_u+dis_v+w) ans=max(ans,disu+disv+w)
d
i
s
u
=
m
a
x
(
d
i
s
u
,
d
i
s
v
+
w
)
dis_u=max(dis_u,dis_v+w)
disu=max(disu,disv+w)
[Done]
2.P2344 理智的cow
solution:
虽然这个题目可以通过朴素的dp+简单的剪枝
O
(
n
2
)
O(n^2)
O(n2)过,可是刷题在于学习。我们设
d
p
i
dp_i
dpi表示在第i头牛的时候的方案数,那么对于转移我们有:
f
i
=
∑
j
=
1
j
<
=
i
d
p
j
∗
(
s
u
m
i
−
s
u
m
j
>
=
0
)
f_i=\sum\limits_{j=1}^{j<=i}dp_j*(sum_i-sum_j>=0)
fi=j=1∑j<=idpj∗(sumi−sumj>=0),又因为,发现有要求
j
<
i
,
s
u
m
j
<
=
s
u
m
i
j<i,sum_j<=sum_i
j<i,sumj<=sumi,那么问题可以变为二维偏序问题,即以序号为x维,sum为y为有一个二维的矩形,问在点
(
n
,
s
u
m
n
)
(n,sum_n)
(n,sumn),左下方有多少点,用树状数组维护即可
[Done]
3.P3914染色计数
solution:
方案数dp,设 f i , j f_{i,j} fi,j表示以i为根,且i为j颜色时的子树的方案数,那么根据乘法原理有 f i , j = ∏ f s o n i , c , c ! = j f_{i,j}=\prod f_{son_i,c},c!=j fi,j=∏fsoni,c,c!=j,然后考虑优化。
我们不需要枚举儿子,我们可以提前预处理出所有的和,然后减去不合法的就求出了颜色的方案数,优化为了
O
(
n
2
)
O(n^2)
O(n2)
[Done]
4.P1899魔法物品
solution:
对于普通物品直接卖出,然后对于亏本的魔法商品也直接卖出( P 1 > P 2 − m P_1>P_2-m P1>P2−m)我们设答案为s,那么我们按照 P 2 − P 1 P_2-P_1 P2−P1排序,然后得到s
分类讨论
1.如果s>m那么 a n s = s + ∑ i = 1 i < = z ( P i , 2 − m ) ans=s+\sum\limits_{i=1}^{i<=z}(P_{i,2}-m) ans=s+i=1∑i<=z(Pi,2−m)
2.如果s<m说明我们需要卖掉一些不亏本的魔法商品,来买卷轴。
那么我们选的出来卖的东西一定要满足性质
s
+
∑
p
i
,
1
>
=
m
s+\sum p_{i,1}>=m
s+∑pi,1>=m,并且最小化我们卖出去的商品的(
P
2
−
P
1
−
m
P_2-P_1-m
P2−P1−m)之和,考虑dp,设
f
i
f_i
fi表示卖出有价值的商品共i元的时候的最小损失
f
i
=
m
i
n
(
f
i
,
f
i
−
P
j
,
1
+
d
j
)
f_i=min(f_i,f_{i-P_j,1+d_j})
fi=min(fi,fi−Pj,1+dj)
[Done]
5.长乐OI国庆集训Day1 (#撰写博客)
solution:
/我真菜我真菜我真菜,我真傻真的我单知道我连A组都不能AK,就不应该去乱搞的/
简单思路:设 d p i dp_i dpi表示原字符串中以i结尾不含 哲 学 哲学 哲学字符的合法字符串的最小损失代价 d p i = m i n ( d p j ) + a i j ∈ ( S ) dp_i=min(dp_j)+a_i \space j\in(S) dpi=min(dpj)+ai j∈(S),并且i为最后一个删去的 哲 学 因 子 哲学因子 哲学因子,可以用单调队列优化以及保证合法
解释一下为什么可以用单调队列维护合法性:因为我们从j转移到i,那么说明S的 [ j + 1 , i − 1 ] [j+1,i-1] [j+1,i−1]之间是不存在任何的 哲 学 哲学 哲学字符的,也就是说我们对于一个i,枚举 1 − m 1-m 1−m的字符串T,设其长度为 l e n j len_j lenj,那么 S [ i − 1 , i − l e n j ] ! = T [ j ] S[i-1,i-len_j]!=T[j] S[i−1,i−lenj]!=T[j],如果出现,我就需要删除区间内的一个点(因为是dp,要求出每个状态,那么删去的肯定是i),又考虑到若有多个T,我们只需要最靠近i的一个即 k = m i n ( l e n j ) k=min(len_j) k=min(lenj),因为如果选大的会被覆盖。于是我们按照上面的思路,对每个i都求出对应的k。
又因为 f i f_i fi不严格递增,并且k是同样也是不严格递增的,所以可以用单调队列优化
6.长乐OI国庆集训Day2 (#积木大赛)
solution:
考虑倒过来计算严格不递减序列,那么如果最后一段最小就一定是最优的,设
f
i
f_i
fi表示考虑到第i个的时候最多可以分为几段,
s
u
f
i
suf_i
sufi表示以i结尾的最后一段的区间和,那么有
f
i
=
m
a
x
j
<
i
,
s
u
f
j
<
S
i
−
S
j
(
f
j
+
1
)
f_i=max_{j<i,suf_j<S_i-S_j}(f_j+1)
fi=maxj<i,sufj<Si−Sj(fj+1),又因为需要
s
u
f
j
+
f
j
suf_j+f_j
sufj+fj递增,所以维护一个递增的单调序列
code
6.长乐OI国庆集训Day4 (#历经磨难)
solution:
首先根据题意写出朴素的方程式
d
p
i
,
j
=
m
a
x
(
d
p
k
,
j
+
c
i
−
z
∗
(
i
s
i
dp_{i,j}=max(dp_{k,j}+c_i-z*(is_i
dpi,j=max(dpk,j+ci−z∗(isi&&
i
s
k
)
)
is_k))
isk))
(
k
∈
(
i
−
q
,
i
−
p
)
)
(k\in(i-q,i-p))
(k∈(i−q,i−p))很像我们之前做过的切露其那道题,于是不用考虑z的部分分我们就直接单调队列维护单调递减的
d
p
i
+
c
i
dp_i+c_i
dpi+ci可以过掉了,然后对于考虑z的情况,可以考虑把原来的单调队列拆成被整除和不被整除的两个部分code
7.P3957 跳房子
solution:
首先因为答案满足单调性,所以可以二分答案,dp验证。
然后考虑dp方程式,设 d p i dp_i dpi表示到达第i个点时的最大得分,然后根据题意得到转移方程: f i = m a x ( f j + c i ) j ∈ ( d i s i − d − m i d , d i s i − m a x ( 1 , d − m i d ) ) f_i=max(f_j+c_i)j\in(dis_i-d-mid,dis_i-max(1,d-mid)) fi=max(fj+ci)j∈(disi−d−mid,disi−max(1,d−mid)),然后呢我们发现这个 f j f_j fj单调递增,且求最大值,所以考虑单调队列优化,单调队列维护单调递减的 d p j dp_j dpj,每次取队首并及时处理过期答案
8.长乐OI国庆集训Day6 (#铲雪问题)
solution:
我们可以先每个点单独处理,然后再考虑把能够合并的操作合并。对于合并操作,对于单一节点,最优方案为先和儿子节点合并,然后和父亲节点合并。设 f i f_i fi表示 i i i能和儿子匹配的最大贡献,设 g i g_i gi表示以 i i i为根的子树最大匹配情况下对父亲的贡献
分类讨论转移:
我们设所有儿子都可以与目前节点合并,贡献为
r
e
s
res
res
- 2 ∗ a x < r e s 2*a_x< res 2∗ax<res时,所有儿子节点可以直接和目前节点合并,子树对父亲的贡献为 g x = 0 g_x=0 gx=0
- r e s < a x res<a_x res<ax时,此时我们可以把儿子们单独合并,然后对父亲的贡献就是 g x = a x g_x=a_x gx=ax
- r e s > a x res>a_x res>ax && r e s ≤ a x ∗ 2 res\leq a_x*2 res≤ax∗2,此时子树部分可以进行一次合并,而对父亲节点还会有 a x ∗ 2 − r e s a_x*2-res ax∗2−res的贡献
9.P5308 quiz
solution:
设 f i f_i fi表示还剩i个人时的最大获奖金额,显而易见的是 f i = max 0 < j ≤ i f j + i − j i f_i=\max_{0<j\leq i}f_j+\frac{i-j}{i} fi=max0<j≤ifj+ii−j,然后很显然的斜率优化,我们设 f j + i − j i > f k + i − k i f_j+\frac{i-j}{i}>f_k+\frac{i-k}{i} fj+ii−j>fk+ii−k,就可以得到当 f j − f k j − k > 1 i \frac{f_j-f_k}{j-k}>\frac{1}{i} j−kfj−fk>i1时 j j j比 i i i更优,所以单调队列维护斜率,对于k的限制直接上wqs二分,减去 m i d mid mid进行限制,最后加上
10.P2016 战略游戏
solution:
肉眼可见的树上dp,设 f i , 0 / 1 f_{i,0/1} fi,0/1表示以i位根节点且有/无士兵的最小答案,转移也很简单
f i , 0 = ∑ v ∈ s o n i f v , 1 f_{i,0}=\sum_{v\in son_i}f_{v,1} fi,0=∑v∈sonifv,1
f i , 1 = 1 + ∑ v ∈ s o n i min ( f v , 0 , f v , 1 ) f_{i,1}=1+\sum_{v\in son_i}\min (f_{v,0},f_{v,1}) fi,1=1+∑v∈sonimin(fv,0,fv,1)
11.P1131 时态同步
solution:
肉眼可见树形结构,题意为求最小操作使得叶子节点到根节点的距离一样,考虑这个距离为叶子节点中到根节点的最大距离。然后开始dp,设
f
[
i
]
f[i]
f[i],表示以i为根节点的子树完成时态同步需要的最小代价,
d
i
s
[
i
]
dis[i]
dis[i],表示以i为根节点的子树中到根节点的最大距离。
进行转移:
$dis[i]=\max_{v\in son_i}(dis[i],dis[v]+w[i,v]) $
f [ i ] = ∑ v ∈ s o n i f [ v ] + d i s [ i ] − d i s [ v ] − w [ i , v ] f[i]=\sum_{v\in son_i}f[v]+dis[i]-dis[v]-w[i,v] f[i]=∑v∈sonif[v]+dis[i]−dis[v]−w[i,v]
12.P4163 排列
solution:
一共有两种方法求但是stl的方法被新数据卡掉了。但是还是有必要进行补充。
1.stl中的next_permutation可以枚举出有序序列的所有排列,一般与do while搭配使用
2.状压dp,设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示选数状态为i时,模数为j的方案数。
转移为:
d
p
[
s
∣
1
<
<
(
i
−
1
)
]
[
(
k
∗
10
+
a
[
i
]
)
m
o
d
d
]
=
d
p
[
s
]
[
k
]
dp[s|1<<(i-1)][(k*10+a[i])\bmod d]=dp[s][k]
dp[s∣1<<(i−1)][(k∗10+a[i])modd]=dp[s][k]
13.P3572 PTA-Little Bird
solution:
设 d p [ i ] dp[i] dp[i]表示跳到第i棵树时的最小劳累值,转移为 f [ i ] = min 1 ≤ j ≤ k d p [ j ] + ( h [ j ] < = h [ i ] ) f[i]=\min_{1 \leq j \leq k}dp[j]+(h[j]<=h[i]) f[i]=min1≤j≤kdp[j]+(h[j]<=h[i]),发现当 x < y x<y x<y, f [ x ] > f [ y ] f[x]>f[y] f[x]>f[y]或者KaTeX parse error: Expected 'EOF', got '&' at position 11: f[x]==f[y]&̲&h[x]<=h[y]时就无需考虑转移,单调队列维护即可
14.猴猴吃香蕉
大致题意:给你n个数,问你有多少种方案合法(合法条件是选的数相乘为K)
sol:
先对k进行因数分解,把k的因子存下来,并且把不是k因子的数筛掉。设
f
[
i
]
f[i]
f[i]表示当乘积为i时的方案数,那么转移方程为
f
[
b
]
+
=
f
[
b
/
a
]
f[b]+=f[b/a]
f[b]+=f[b/a],其中b为心情值,a为甜度。如果相等就++。然后因为k巨大,所以考虑用map存
code
15.考试题目 数塔路径
sol:
考虑正反向各跑一遍dp,记作
f
,
g
f,g
f,g,易得答案为
max
j
=
1
i
(
f
[
i
]
[
j
]
+
g
[
i
]
[
j
]
−
a
[
i
]
[
j
]
)
\max\limits_{j=1}^{i}(f[i][j] + g[i][j]-a[i][j])
j=1maxi(f[i][j]+g[i][j]−a[i][j]),然后对于每个每层i,求出最大值与次大值,并且记录最大值出现的位置j,如果这个位置被占用就输出次大值否则为最大值
code
16.考试题目 乐园之旅
sol:
考虑状态,设 f [ i ] [ j ] [ 0 / 1 ] f[i][j][0/1] f[i][j][0/1]表示到第i个设施,用时j,第一个人/第二个人的快乐值,转移醍醐灌顶:
f [ x ] [ i ] [ 0 / 1 ] = ∑ ( x , y ) ∈ E , i + t ( x , y ) + c x + c y < = k f [ y ] [ i + t ( x , y ) + c x + c y ] [ 0 / 1 ] c n t f[x][i][0/1]=\sum\limits_{(x,y)\in E,i+t(x,y)+c_x+c_y<=k}\frac{f[y][i+t(x,y)+c_x+c_y][0/1]}{cnt} f[x][i][0/1]=(x,y)∈E,i+t(x,y)+cx+cy<=k∑cntf[y][i+t(x,y)+cx+cy][0/1]
此时存在可以玩的项目,否则就是
h
x
h_x
hx,就没了
code
17.CF264B Good Sequences
sol:
考虑暴力dp,设 f [ i ] f[i] f[i]表示以i结尾的序列最长的合法序列,转移直接暴力转移 f [ i ] = max 1 < = j < i f [ j ] + 1 f[i]=\max\limits_{1<=j<i}f[j]+1 f[i]=1<=j<imaxf[j]+1复杂度为 O ( n 2 ) O(n^2) O(n2)无法通过此题目,考虑优化双重循环。发现最有可能发生转移的是与 a [ i ] a[i] a[i]有相同因子的数(因为非互质),所以不难想到再维护一个类似堆的东西:维护与 a [ i ] a[i] a[i]有相同因子的最大 f [ j ] f[j] f[j]。具体实现可以先每个质数开一个动态数组,将范围内的倍数存入,然后dp求这个最大的f即可复杂度为 O ( n ∗ Θ ) O(n*\Theta) O(n∗Θ),其中 Θ \Theta Θ为 a i a_i ai的因子个数的平均数
18.[杭二集训 替身使者]
大致题意:
给定n个区间,从每个区间选一个点,若一个地方上有x个点,其贡献为 G ( x ) G(x) G(x),G的计算方式给出,求最大贡献
sol:
一个显然的结论,这些点尽可能的放在一起比分开放更优。因此在最优决策下一定不存在一个点可以到人数最多的点但是不去的情况。考虑区间DP,设
f
[
l
]
[
r
]
f[l][r]
f[l][r]表示所有区间
[
L
,
R
]
[L,R]
[L,R]的答案。dp方程式为:
d
p
[
l
]
[
r
]
=
max
k
∈
[
l
,
r
]
(
d
p
[
l
]
[
k
−
1
]
+
G
(
k
)
+
d
p
[
k
+
1
]
[
r
]
)
dp[l][r]=\max\limits_{k\in[l,r]} (dp[l][k-1]+G(k)+dp[k+1][r])
dp[l][r]=k∈[l,r]max(dp[l][k−1]+G(k)+dp[k+1][r])递归求解即可,因为m太大需要离散化
code
19.P3125Bessie’s Birthday BuffetS
sol:
设 d p [ i ] dp[i] dp[i]表示到i时的最大能量,那么转移很好想 d p [ i ] = m a x ( d p [ j ] − d i s i , j ) + w [ i ] dp[i]=max(dp[j]-dis_{i,j})+w[i] dp[i]=max(dp[j]−disi,j)+w[i],首先可以预处理出任意两点间的dis,因为边权相同采用BFS或者SPFA,然后考虑题目限制,因为要求递增所以转移前按点权排序即可
20.P2885 Telephone WireG
sol:
这种牵一发而动全身的东西一般就考虑dp了,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示到达第i个树并且这颗树的高度为j时的最小费用, d p [ i ] [ j ] = ( j − h [ i ] ) 2 + m i n ( f [ i − 1 ] [ k ] + c ∗ ( a b s ( j − k ) ) ) dp[i][j]=(j-h[i])^2+min(f[i-1][k]+c*(abs(j-k))) dp[i][j]=(j−h[i])2+min(f[i−1][k]+c∗(abs(j−k))),时间复杂度大概为 O ( N ∗ H 2 ) O(N*H^2) O(N∗H2),考虑优化,发现转移的方程为关于j的 a > 0 a>0 a>0型的二次函数,所以当函数递增的时候就不用继续转移了
21.P2340 Cow ExhibitionG
sol:
同样为牵一发而动全身,考虑dp,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i头牛选出来的牛的情商为j时的最大智商 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − e [ i ] ] + I [ i ] ) dp[i][j]=max(dp[i-1][j],dp[i-1][j-e[i]]+I[i]) dp[i][j]=max(dp[i−1][j],dp[i−1][j−e[i]]+I[i]),最后答案枚举情商智商取最大值即可,可以采用滚动数组优化
22.P2890Cheapest PalindromeG
sol:
考虑区间dp,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示把i到j变为回文串的最小代价,方程如下:
d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] ( s [ i ] = = s [ j ] ) dp[i][j]=dp[i+1][j-1](s[i]==s[j]) dp[i][j]=dp[i+1][j−1](s[i]==s[j])
d p [ i ] [ j ] = min ( f [ i + 1 ] [ j ] + min ( d e l [ s [ i ] ] , i n s [ s [ i ] ] ) ) dp[i][j]=\min(f[i+1][j]+\min(del[s[i]],ins[s[i]])) dp[i][j]=min(f[i+1][j]+min(del[s[i]],ins[s[i]]))
d p [ i ] [ j ] = min ( f [ i ] [ j − 1 ] + min ( d e l [ s [ j ] ] , i n s [ s [ j ] ] ) ) dp[i][j]=\min(f[i][j-1]+\min(del[s[j]],ins[s[j]])) dp[i][j]=min(f[i][j−1]+min(del[s[j]],ins[s[j]]))
23.CF9D How many trees?
sol:
神题,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示高度小于j有i个子结点的二叉树个数,dp方程: d p [ i ] [ j ] = d p [ k ] [ j − 1 ] ∗ d p [ i − k − 1 ] [ j − 1 ] dp[i][j]=dp[k][j-1]*dp[i-k-1][j-1] dp[i][j]=dp[k][j−1]∗dp[i−k−1][j−1]
24.CF254C Anagram
sol:
神题,因为是换位串,所以只要 s u m [ t i ] = = s u m [ s i ] ( i ∈ U ) sum[t_i]==sum[s_i](i\in U) sum[ti]==sum[si](i∈U)即可,然后贪心地让加进去的小的放前面, a n s = ∑ i ∈ U s u m [ s i ] < s u m [ t i ] ? ( s u m [ s i ] − s u m [ t i ] ) : 0 ans=\sum\limits_{i\in U} sum[s_i]<sum[t_i]?(sum[s_i]-sum[t_i]):0 ans=i∈U∑sum[si]<sum[ti]?(sum[si]−sum[ti]):0
25.CF11D A Simple Task
sol:
数据范围可知为状压dp,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示经过的点的状态为i,现在在j时的答案,当这个点每经过,且编号不是经过点中最小的时,转移方程为: d p [ k ∣ ( 1 < < j ) ] [ k ] + = d p [ j ] [ i ] ( a [ j ] [ k ] = = 1 ) dp[k|(1<<j)][k]+=dp[j][i](a[j][k]==1) dp[k∣(1<<j)][k]+=dp[j][i](a[j][k]==1),若这个点经过了,并且是第一个点,那么这个时候就形成了一个环,答案加上 d p [ i ] [ k ] dp[i][k] dp[i][k],若不是就跳过,最后注意答案要除2并且减去重边的贡献
26.CF10D LCIS
sol:
神题。考虑求单个串的LIS时的做法,将读入离散化然后设 d p [ i ] dp[i] dp[i]表示以i这数为结尾的最大答案,那么转移显然: d p [ i ] = max ( d p [ j ] ) + 1 ( j < i ) dp[i]=\max(dp[j])+1(j<i) dp[i]=max(dp[j])+1(j<i),求i之前的区间最大值,自然是树状数组了,然后考虑二维,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示第一个串以i这个数结尾,第二个串以j结尾的时的答案,注意因为是公共子串所以j表示的是下标,转移时类推: d p [ i ] [ j ] = max ( d p [ h ] [ k ] ) + 1 ( h < i , k < j ) dp[i][j]=\max(dp[h][k])+1(h<i,k<j) dp[i][j]=max(dp[h][k])+1(h<i,k<j),用二维树状数组维护区间最大
27.最优路线
sol:
考虑公差计算公式: ∑ i = 1 i < = n x i 2 n − x 2 \frac{\sum\limits_{i=1}^{i<=n}x_i^2}{n}-x^2 ni=1∑i<=nxi2−x2,那么把计算式子化简发现: N ∗ ∑ i = 1 i < = n x i 2 − ( s u m ) 2 N*\sum\limits_{i=1}^{i<=n}x_i^2-(sum)^2 N∗i=1∑i<=nxi2−(sum)2,考虑dp,设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示到达i,j这个点且权值之和为k时的最小公差,转移为: d p [ i ] [ j ] [ k ] = m i n ( d p [ i − 1 ] [ j ] [ k − a [ i ] [ j ] ] , d p [ i ] [ j − 1 ] [ k − a [ i ] [ j ] ] ) + b [ i ] [ j ] dp[i][j][k]=min(dp[i-1][j][k-a[i][j]],dp[i][j-1][k-a[i][j]])+b[i][j] dp[i][j][k]=min(dp[i−1][j][k−a[i][j]],dp[i][j−1][k−a[i][j]])+b[i][j],其中 b [ i ] [ j ] = a [ i ] [ j ] 2 b[i][j]=a[i][j]^2 b[i][j]=a[i][j]2
28.CF730J Bottles
sol:
首先对于第一个问题,直接排序就没问题了,对于第二个问题,一个显然的操作就是DP,并且为背包型。考虑最小时间的要求,即我们选的原本有的在需求中要占大部分,设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示前i个瓶子选了j个容积为k时的最大原占有,转移为:
d p [ i ] [ j ] [ k ] = max ( d p [ i ] [ j ] [ k ] , dp[i][j][k]=\max(dp[i][j][k], dp[i][j][k]=max(dp[i][j][k],
max ( d p [ i − 1 ] [ j − 1 ] [ k − b [ i ] ] + a [ i ] , d p [ i − 1 ] [ j ] [ k ] ) ) \max(dp[i-1][j-1][k-b[i]]+a[i],dp[i-1][j][k])) max(dp[i−1][j−1][k−b[i]]+a[i],dp[i−1][j][k]))
最后答案就是 V − d p [ n ] [ a n s 1 ] [ V ] V-dp[n][ans1][V] V−dp[n][ans1][V]
29.CF1077F2 Pictures with Kittens (hard version)
sol:
设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i个选了j个元素,转移为 d p [ i ] [ j ] = max t = i − k t < = i − 1 ( d p [ t ] [ j − 1 ] ) + a [ i ] dp[i][j]=\max\limits_{t=i-k}^{t<=i-1}(dp[t][j-1])+a[i] dp[i][j]=t=i−kmaxt<=i−1(dp[t][j−1])+a[i],单调队列没什么好说的
30.P3118 Moovie MoovingG
sol:
n很小考虑状压,设 d p [ i ] dp[i] dp[i]表示看了的电影种类状态为i时能看到最远的时长,转移: d p [ i ∣ ( 1 < < ( j − 1 ) ) ] = d p [ i ] + max s t j ≤ f i ( e d j − f i ) dp[i|(1<<(j-1))]=dp[i]+\max\limits_{st_j\le f_i}(ed_j-f_i) dp[i∣(1<<(j−1))]=dp[i]+stj≤fimax(edj−fi),最后扫一遍,取最小即可
31.P4187Stamp PaintingG
sol:
ORZ 蓝天星辰
最后的状态肯定是存在一个大于等于K的区间颜色相同,但是正向不好算,考虑容斥。设 d p [ i ] dp[i] dp[i]表示从1到i填涂没有超过k的区间颜色相同,转移:
d p [ i ] = d p [ i − 1 ] ∗ m ( i < k ) dp[i]=dp[i-1]*m(i<k) dp[i]=dp[i−1]∗m(i<k)
d p [ i ] = ∑ j − k + 1 ≤ j i − 1 d p [ j ] ∗ ( m − 1 ) dp[i]=\sum\limits_{j-k+1\le j}^{i-1}dp[j]*(m-1) dp[i]=j−k+1≤j∑i−1dp[j]∗(m−1)(i>k)
最后答案就是 m n − d p [ n ] m^n-dp[n] mn−dp[n]
32.P3116 Meeting Time S
sol:
DAG,考虑拓扑,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示用j时间能不能到达i这个点,转移为 d p [ v ] [ j ] = d p [ u ] [ j − w [ u , v ] ] dp[v][j]=dp[u][j-w[u,v]] dp[v][j]=dp[u][j−w[u,v]],最后枚举时间,看是否存在相同的时间满足两个式子均为1
33.雅礼集训 红与蓝
sol:
设
d
p
[
u
]
dp[u]
dp[u]={1,0,-1}分别表示这个点一定会变为红,一定会变为蓝色和谁先染其子树内的叶子就是什么颜色,考虑动态规划求dp,记
c
o
c_o
co,表示这个点的叶子中有多少个点是红色必胜同理
c
1
c_1
c1表示蓝色必胜,若这个节点的
c
0
>
c
1
c_0>c_1
c0>c1那么
d
p
i
=
1
dp_i=1
dpi=1,反正就为
d
p
i
=
0
dp_i=0
dpi=0,若相等则为
−
1
-1
−1,那么问题变得简单起来,若
d
p
1
=
1
dp_1=1
dp1=1,答案就是所有没染色的叶子节点,反之为-1,若为-1,我们肯定想要它的子树中
c
1
>
c
0
c_1>c_0
c1>c0。不妨记
c
u
=
c
1
−
c
0
c_u=c_1-c_0
cu=c1−c0,然后dfs找是否存在儿子v满足
c
v
=
0
/
−
1
c_v=0/-1
cv=0/−1,那么就一遍dfs找到这个叶子就可以了
code
34.棋盘大战
sol:
设 d p [ u ] [ 0 / 1 ] dp[u][0/1] dp[u][0/1]表示目前在u,要最大化/最小化的叶子,在u子树中的叶子里排名第几。可以通过dep来判断是先手还是后手考虑转移:
d p [ u ] [ 1 ] = max v ∈ s o n u ( f [ v ] [ 1 ] + s i z e [ u ] − s i z e [ v ] ) dp[u][1]=\max\limits_{v\in son_u}(f[v][1]+size[u]-size[v]) dp[u][1]=v∈sonumax(f[v][1]+size[u]−size[v])(先手时,你要最大化排名)
d p [ u ] [ 1 ] = ∑ v ∈ s o n [ u ] ( f [ v ] [ 1 ] − 1 ) + 1 dp[u][1]=\sum\limits_{v\in son[u]}(f[v][1]-1)+1 dp[u][1]=v∈son[u]∑(f[v][1]−1)+1
反之同理
35.扭动的树
sol:
因为二叉排序树按照键值排序的本质是中序遍历,所以按照键值排序从小到大排序即可,又在中序遍历中,一颗子树的值一定是一个区间,于是考虑区间dp,设
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]表示在区间
[
i
,
j
]
[i,j]
[i,j]建立子树的最大sum值之和,且子树的根节点为第k个数。又因为为二叉树所以k只有可能为
i
−
1
i-1
i−1or
j
+
1
j+1
j+1所以直接把k维变为0/1即可,转移时考虑限制即可
code
36/37.ZUMA
sol:
显然为区间DP,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示消去i到j这个区间所需的最小炮弹数量,但是这样的状态设计不能表示出插入数带来的影响,所以加一维, d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示区间i到j前,加上k个 a [ i ] a[i] a[i]并且消去这整个区间所需的代价,考虑转移:
1. d p [ i ] [ j ] [ k ] = d p [ i ] [ j ] [ k + 1 ] + 1 dp[i][j][k]=dp[i][j][k+1]+1 dp[i][j][k]=dp[i][j][k+1]+1 ( k + 1 ≠ m ) (k+1\not =m) (k+1=m)
2. d p [ i ] [ j ] [ k ] = d p [ i + 1 ] [ j ] [ 0 ] dp[i][j][k]=dp[i+1][j][0] dp[i][j][k]=dp[i+1][j][0]
3. d p [ i ] [ j ] [ k ] = d p [ i ] [ m i d − 1 ] [ 0 ] + d p [ m i d ] [ j ] [ k + 1 ] ( a i = a m i d ) dp[i][j][k]=dp[i][mid-1][0]+dp[mid][j][k+1](a_i=a_{mid}) dp[i][j][k]=dp[i][mid−1][0]+dp[mid][j][k+1](ai=amid)
38/39.方块消除
sol:
先把散块合并,然后考虑区间dp,设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示消去 [ i , j ] [i,j] [i,j]然后区间后面有k个与j相同的块得最大得分,同样分类讨论:
1. d p [ i ] [ j ] [ k ] = d p [ i ] [ j − 1 ] + ( l e n r + k ) 2 dp[i][j][k]=dp[i][j-1]+(len_{r}+k)^2 dp[i][j][k]=dp[i][j−1]+(lenr+k)2(i,j和后面的k单独消除)
2. d p [ i ] [ j ] [ k ] = d p [ i ] [ m i d ] [ l e n r + k ] + d p [ i + 1 ] [ j − 1 ] [ 0 ] dp[i][j][k]=dp[i][mid][len_r+k]+dp[i+1][j-1][0] dp[i][j][k]=dp[i][mid][lenr+k]+dp[i+1][j−1][0](a[mid]=a[k],把mid到r全部消除,接上后消除新的i到r)
40.CF31E TV game
sol:
一道很有意思的背包类型dp,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示i个给A,j个给B能够构成的最大A+B,转移考虑倒推:
d p [ i ] [ j ] = max ( d p [ i ] [ j ] , d p [ i − 1 ] [ j ] + ( s [ i ] − ′ 0 ′ ) i − 1 ) [ i > 0 ] dp[i][j]=\max(dp[i][j],dp[i-1][j]+(s[i]-'0')^{i-1})[i>0] dp[i][j]=max(dp[i][j],dp[i−1][j]+(s[i]−′0′)i−1)[i>0]
d p [ i ] [ j ] = max ( d p [ i ] [ j ] , d p [ i ] [ j − 1 ] + ( s [ j ] − ′ 0 ′ ) j − 1 ) [ j > 0 ] dp[i][j]=\max(dp[i][j],dp[i][j-1]+(s[j]-'0')^{j-1})[j>0] dp[i][j]=max(dp[i][j],dp[i][j−1]+(s[j]−′0′)j−1)[j>0]
最后答案dfs输出
41.CF557B
sol:
首现要求和为m的倍数,那么就是和在模m意义下为0,可以先把每个数先对m取模,然后再作背包,但是背包的复杂度为 O ( N 2 ) O(N^2) O(N2),这里显然不行.但是注意到任何一个数可以被表示为前后两个前缀和之差的形式,所以我们只要考虑这k个前缀和即可,取模后这n个数的取值范围在 [ 0 , M ) [0,M) [0,M),那么如果n>m,说名必然有重复的元素(即前缀和),我们对这两个作差得到的子序列就是答案故必然合法.
于是范围缩小,作背包,设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i个数选的数和在模m意义下为j时是否可行,转移 d p [ i ] [ ( j + a [ i ] ) m o d m ] ∣ = d p [ i ] [ j ] dp[i][(j+a[i])\bmod m]|=dp[i][j] dp[i][(j+a[i])modm]∣=dp[i][j], d p [ i ] [ j ] ∣ = d p [ i − 1 ] [ j ] dp[i][j]|=dp[i-1][j] dp[i][j]∣=dp[i−1][j]
42.CF517B
sol:
题目相当于把下标模k相同的放在一组,然后最终答案就是每组元素相邻元素之差的和,显然的是,如果一组中的元素是相邻的(数值),那么他的贡献就是最小的,于是可以直接对原数组排序,然后可以发现,有 n m o d k n\bmod k nmodk个元素所在组的元素个数为 k n + 1 \frac{k}{n}+1 nk+1, k − n m o d k k-n\bmod k k−nmodk个元素所在组组内元素个数为 n / k n/k n/k,设dp[i][j]表示第一种选了i组,第二种选了j组的最小答案。转移:
d p [ i ] [ j ] = min ( d p [ i ] [ j ] , d p [ i − 1 ] [ j ] + a [ i ∗ n u m a + j ∗ n u m b ] − a [ ( i − 1 ) ∗ n u m a + j ∗ n u m b + 1 ] ) dp[i][j]=\min(dp[i][j],dp[i-1][j]+a[i*numa+j*numb]-a[(i-1)*numa+j*numb+1]) dp[i][j]=min(dp[i][j],dp[i−1][j]+a[i∗numa+j∗numb]−a[(i−1)∗numa+j∗numb+1])
d p [ i ] [ j ] = min ( d p [ i ] [ j ] , d p [ i ] [ j − 1 ] + a [ i ∗ n u m a + j ∗ n u m b ] − a [ i ∗ n u m a + ( j − 1 ) ∗ n u m b ] ) dp[i][j]=\min(dp[i][j],dp[i][j-1]+a[i*numa+j*numb]-a[i*numa+(j-1)*numb]) dp[i][j]=min(dp[i][j],dp[i][j−1]+a[i∗numa+j∗numb]−a[i∗numa+(j−1)∗numb])
因为排序后一组的贡献就是最大值减最小值了
43.CF486D
sol:
设 d p [ u ] dp[u] dp[u]表示当根结点为u时子树内的合法答案,我们不妨把根定为最大值,如果合法就转移 d p [ u ] = ( d p [ u ] + d p [ u ] ∗ d p [ v ] ) dp[u]=(dp[u]+dp[u]*dp[v]) dp[u]=(dp[u]+dp[u]∗dp[v])(自己的搭配上儿子的都满足所以是这样),注意为去重如果出现 a [ v ] = a [ u ] a[v]=a[u] a[v]=a[u]那么必须要v<u,才可以进行转移
44.P3607
sol:
因为是子序列,且n很小但不是状压,所并且是区间翻转,所以考虑区间dp,设 d p [ l ] [ r ] dp[l][r] dp[l][r],表示区间l,r(子序列)翻转后的最大答案,但是并不好转移,所以注意到不下降自序列的特点与最大值最小值有关,所以设 d p [ l ] [ r ] [ d o w n ] [ u p ] dp[l][r][down][up] dp[l][r][down][up]down,up表示值域。转移:
d p [ l ] [ r ] [ d o w n ] [ u p ] = max ( d p [ l ] [ r ] [ d o w n + 1 ] [ u p ] , d p [ l ] [ r ] [ d o w n ] [ u p − 1 ] ) dp[l][r][down][up]=\max(dp[l][r][down+1][up],dp[l][r][down][up-1]) dp[l][r][down][up]=max(dp[l][r][down+1][up],dp[l][r][down][up−1])
d p [ l ] [ r ] [ d o w n ] [ u p ] = max ( d p [ l ] [ r ] [ d o w n ] [ u p ] , d p [ l + 1 ] [ r ] [ d o w n ] [ u p ] + ( a [ l ] = = d o w n ) ) dp[l][r][down][up]=\max(dp[l][r][down][up],dp[l+1][r][down][up]+(a[l]==down)) dp[l][r][down][up]=max(dp[l][r][down][up],dp[l+1][r][down][up]+(a[l]==down))
d p [ l ] [ r ] [ d o w n ] [ u p ] = max ( d p [ l ] [ r ] [ d o w n + 1 ] [ u p ] , d p [ l ] [ r − 1 ] [ d o w n ] [ u p ] + ( a [ r ] = = u p ) ) dp[l][r][down][up]=\max(dp[l][r][down+1][up],dp[l][r-1][down][up]+(a[r]==up)) dp[l][r][down][up]=max(dp[l][r][down+1][up],dp[l][r−1][down][up]+(a[r]==up))
d p [ l ] [ r ] [ d o w n ] [ u p ] = max ( d p [ l ] [ r ] [ d o w n ] [ u p ] , d p [ l − 1 ] [ r − 1 ] [ u p ] [ d o w n ] + ( a [ l ] = = u p ) + ( a [ r ] = = d o w n ) ) dp[l][r][down][up]=\max(dp[l][r][down][up],dp[l-1][r-1][up][down]+(a[l]==up)+(a[r]==down)) dp[l][r][down][up]=max(dp[l][r][down][up],dp[l−1][r−1][up][down]+(a[l]==up)+(a[r]==down))
对于最后,因为题目中的转移方式可以拆分为首尾的单独转移,所以有最后的式子
45.P6647 Tourism
sol:
考虑朴素的dp:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示前i天去了j天的最大价值,转移显然:
d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ x ] + m a x ( a x … … a j − 1 ) ) dp[i][j]=max(dp[i-1][x]+max(a_x……a_{j-1})) dp[i][j]=max(dp[i−1][x]+max(ax……aj−1))
目前为止我们可以知道的优化就有两个:线段树优化以及单调栈分别优化dp+常数和最大的a。
只有一个问题没有解决:在最小的天数内完成,这种带转移次数限制的让我们很自然的想到了wqs二分中的trick,我们可以在转移的时候-INF即可,那么最终的转移式子如下:
d p [ j ] = m a x ( d p [ x ] + m a x ( a x … … a j − 1 ) ) − i n f dp[j]=max(dp[x]+max(a_x……a_{j-1}))-inf dp[j]=max(dp[x]+max(ax……aj−1))−inf
简单树上贺题
题单
从上但不仅从上刷题
1.P4826
solution:
发现是安排 n − 1 n-1 n−1个决斗,很容易想到树,于是我们可以任意两头牛之间连边,边权为 a i ⊕ a j a_i\oplus a_j ai⊕aj,然后跑一遍最大生成树即可
2.P6047最小路径
solution:
发现是 ∑ a i ∑ b i \frac{\sum a_i}{\sum b_i} ∑bi∑ai的最小值,一个0/1分数规划,那么我们二分设 a n s < = k ans<=k ans<=k,那么一个点的点权 v a l i = a i − k ∗ b i val_i=a_i-k*b_i vali=ai−k∗bi,那么问题就变为了找一条长度为m的链满足点权之和小于等于0。于是考虑树形DP,设 f i , j f_{i,j} fi,j表示以i为根,向下长度为j的最小点权值之和,那么考虑转移
f i , j = v a l i + m i n ( f y , i − 1 ∣ ∣ y 为 i 的 儿 子 ) f_{i,j}=val_i+min(f_{y,i-1}||y为i的儿子) fi,j=vali+min(fy,i−1∣∣y为i的儿子)
f i , 0 = v a l i f_{i,0}=val_i fi,0=vali
那么最终的答案 a n s = m i n ( f i , m , 以 及 需 要 折 一 下 的 链 ) ans=min(f_{i,m},以及需要折一下的链) ans=min(fi,m,以及需要折一下的链)
可以考虑前缀和&&DS优化,设 d p i , j dp_{i,j} dpi,j表示根i,到第j层儿子的链的最小点权和,设 p r e x pre_x prex表示从根到x的路径上的val之和,那么有
f i , j = m i n ( f y , i − 1 y 为 i 的 儿 子 ) , f i , 0 = p r e i f_{i,j}=min(f_{y,i-1}y为i的儿子),f_{i,0}=pre_i fi,j=min(fy,i−1y为i的儿子),fi,0=prei
最后答案就是之前的情况,最后利用之前一道题目学到的长链剖分进行优化,重链的直接copy,轻链的暴力转移
3.P6037 Ryoko的探索
solution:
n个点,n个边,说明是基环树,发现进入环以后会有两条边可以走,我们只会选择美观度高的,提前通过拓扑求出那条边然后最后减去即可
[Done]
4.P1961 最轻的天平
solution:
发现是二叉树的结构,于是我们可以构建二叉树,如果是叶子节点,边权就为1,否则设
p
=
a
[
l
]
∗
L
∗
a
[
r
]
∗
R
/
g
c
d
(
a
[
l
]
∗
L
,
a
[
r
]
∗
R
)
,
点
权
为
p
/
a
[
l
]
+
p
/
a
[
r
]
p=a[l]*L*a[r]*R/gcd(a[l]*L,a[r]*R),点权为p/a[l]+p/a[r]
p=a[l]∗L∗a[r]∗R/gcd(a[l]∗L,a[r]∗R),点权为p/a[l]+p/a[r],然后就是找入度为0的根,其答案就为最小答案
[Done]
5.猴猴吃苹果
题目大意:根节点给出的树上,每次走没走过的节点最多的路径,若有多条则选择终点字典序最小的那一条
sol:
其实是可以树剖的因为可以需要查询区间和和实行区间减法,但是需要一定操作得到一个点到达其他点的最长路径。(树链剖分写法)
dfs序写法:因为走过的点的点权会消失,所以从目前的点出发和从终点出发的答案是一样的,所以先一遍dfs得到每个叶子节点的深度,按深度排序后,让点一个一个往上面跳,每跳一步答案就加一,然后到达根节点后按答案排序,从小到大就是最终的序列
code
6.猴猴的比赛
题目大意:给两颗树,求满足使得在两颗树上都存在u是v的祖先的点对 ( u , v ) (u,v) (u,v)的个数
sol:
先对其中一棵树进行dfs得到dfs序从而得到其管辖的区间(l,r),并且赋予点权1,然后dfs遍历第二棵树的时候对其字数求区间和即可。树状数组维护
code
7.NOIP 国庆集训 景点距离
sol:
一道比较ex人的树形dp题,首先Orz @desize,(傻逼东西jc我)我场切。我们设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示到达i的点,经过j条边的路径个数(点对个数也可),设
s
[
i
]
[
j
]
s[i][j]
s[i][j]表示以i为根时的树上的值(同f意义只是说是整个树),然后我们先dfs预处理出每个节点的f,s,然后计算以限制为k的答案,计算答案就是(1->k)的ans之和。然后删点,我们就计算删去后新的f,s,ans。注意的是计算新的f,s,ans时需要先减去之前的值s,然后加上tmp即可
code
7.NOIP 国庆集训 旅行计划
sol:
暴力思想:topo找环,暴力删边
优化暴力,知道树的直径只有可能两种可能:
1.在子树中的直径
2.子树中的直径加上环上的距离
考虑如何快速找出这两个的最大值,直接dfs处理出以环上的点为根的子树内的树的直径,然后处理出环上的前缀和和后缀和。
分类讨论,如果x,y在断边的同侧则为
d
e
p
t
h
x
+
d
e
p
t
h
y
+
s
y
−
s
x
depth_x+depth_y+s_y-s_x
depthx+depthy+sy−sx,或者反过来一样的,如果不在同侧,那么答案为
d
e
p
t
h
x
+
d
d
e
p
t
h
y
+
s
k
−
(
s
x
−
s
y
)
depth_x+ddepth_y+s_k-(s_x-s_y)
depthx+ddepthy+sk−(sx−sy)即可,然后每次计算的时候取最值即可
code
8.雅礼联考 ZYT的答案
链接是假的别看了
ZL中学由 栋教学楼组成,用 条道路连接成一棵树
为了 期末考,ZYT取得了 份答案,但是由于交接不便,这 份答案被
藏在在这些教学楼中,每一份答案都被一把钥匙锁在盒子里。
已知这 份答案的位置 以及的每份答案的钥匙的位置 ,每一份答案对
于提高他的期末考成绩都有一定的影响,用一个值 表示
但是由于不确定答案的真实性, 可能会是负数
这天ZYT准备拿这些答案,但是由于ZYT的行动方式过于诡异,如果经过同
一个地方两次就会被抓去训话
ZYT可以从任意一个地方开始行动,在任意一个地方结束行动,且每到达一
栋教学楼后,他一定会先收集钥匙,一定会再拿取答案。
请你帮ZYT拿到最好的期末考分数,即最大的 之和
简化题意的话:就是求最大价值路径,有价值的路径必须经过一对对应的x,y。
时间复杂度要求: O ( m l o g n ) O(mlogn) O(mlogn)
sol:
分类讨论,然后化为区间加,最后求最大值
9.CF609E Minimum spanning tree for each edge
sol:
一道比较简单的拼夕夕题目因为老师说要讲,直接上认真的
10.CF141E Clearing Up
sol:
考虑验证和法,首先排除n为偶数的情况,然后直接开始先放S,如果放不满(n-1)/2,也是错的,再放M标记一下哪些必须放,然后再看总放的边是不是等于n-1,如果不是也不合法,然后再重新建一次树,先用M,并且先用标记了的M,同之前的方法验证
11.P5666 树的重心
sol:
中规中矩的csp题目,反正我不会。
考虑暴力的思路,暴力枚举删边dfs找重心 O ( n 2 ) O(n^2) O(n2),如果单独处理链和完全二叉树可以得到更高的分(完全二叉树的重心就是根节点)
好的考虑暴力的优化,因为是暴力删边找,所以想到换根,然而如何换?知道重心出现的位置是在根节点的重链上或者它的父亲节点,于是可以倍增处理设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示以i为起点沿着重链的方向跳 2 j 2^j 2j步到达的点,然后就按先前的暴力思路处理即可,重心的充要条件 m a s i z e s o n u < = s i z e u / 2 masize_{son_u} <= size_u/2 masizesonu<=sizeu/2
12.考试题目 三只企鹅
sol:
我直接念ppt了啊
设1为根, s u m [ x ] sum[x] sum[x]表示x到根的路径和。设空投操作有cnt次,第i次操作的城市为 c [ i ] c[i] c[i],那么到第i次的查询操作的答案就可以写成:
∑ i = 1 c n t ( s u m [ c [ i ] ] + s u m [ x ] − 2 ∗ s u m [ L C A ( c [ i ] , x ) ] ) = ∑ i = 1 c n t s u m [ c [ i ] ] + c n t ∗ s u m [ i ] − 2 ∗ ∑ i = 1 c n t s u m [ L C A ( c [ i ] , x ) ] \sum\limits_{i=1}^{cnt}(sum[c[i]]+sum[x]-2*sum[LCA(c[i],x)])=\sum\limits_{i=1}^{cnt}sum[c[i]]+cnt*sum[i]-2*\sum\limits_{i=1}^{cnt}sum[LCA(c[i],x)] i=1∑cnt(sum[c[i]]+sum[x]−2∗sum[LCA(c[i],x)])=i=1∑cntsum[c[i]]+cnt∗sum[i]−2∗i=1∑cntsum[LCA(c[i],x)]
于是每个空投而言,就相当于每个 c [ i ] c[i] c[i]到1的路径上的边加上边权
对于每个查询操作求出x到1的路径和即可
∑
i
=
1
c
n
t
s
u
m
[
L
C
A
(
c
[
i
]
,
x
)
]
\sum\limits_{i=1}^{cnt}sum[LCA(c[i],x)]
i=1∑cntsum[LCA(c[i],x)]
code
13.P1623
sol:
建立最短路树,然后考虑新的答案,显然为 d i s [ x ] + [ d i s [ y ] + w [ x , y ] − d i s [ i ] dis[x]+[dis[y]+w[x,y]-dis[i] dis[x]+[dis[y]+w[x,y]−dis[i], d i s [ i ] dis[i] dis[i]确定,最小化 d i s [ x ] + d i s [ y ] + w dis[x]+dis[y]+w dis[x]+dis[y]+w,于是以此为关键词对边排序,然后考虑一条边对那些点有贡献,显然为 x − > l c a , l c a − > y x->lca,lca->y x−>lca,lca−>y,换言之其路径上的点,又因为排序带来的最优性,每条边仅会更新一次,并查集维护即可
图论问题
题单
1.P1768 天路
solution:
即求
m
i
n
∑
v
i
∑
p
i
{min}\frac{\sum v_i}{\sum p_i}
min∑pi∑vi,与0/1分数规划类似,我们二分答案,那么有不等式
m
i
d
∗
∑
p
i
−
∑
v
i
<
=
0
mid*\sum p_i-\sum v_i<=0
mid∗∑pi−∑vi<=0,那么我们把每条边边权改为
m
i
d
∗
p
−
v
mid*p-v
mid∗p−v,然后dfs+spfa求负环即可,注意是有向图
[Done]
2.CF437C
solution:
一道思维题(qaq)考虑删边,删掉一条边的代价为
m
i
n
(
u
,
v
)
min(u,v)
min(u,v)
[Done]
3.P1783海滩防御
solution:
加强版本的奶酪,只需要考虑两维
x
,
y
x,y
x,y,并查集进行维护
[Done]
4.[私题]
solution :
考场上打了tarjan后面才发现是无向图,其实道理很简单,先看 n = = m n==m n==m,然后判断重边和自环,最后并查集维护即可
tips:找环方法
5.「NOIP2021 国庆集训 B 组 Day2」#染色问题
solution:
对于无环的情况,答案就是图中的最长链,因为我们可以在处理最长链的过程中把其他的点同时处理掉
而对于有环的情况下,我们考虑通过Tarjan算法求出所有的联通块,我们知道每个联通块内的点只能选一个,并且选了以后与这个联通块相连的联通块都不能选,于是我们可以缩点,点的代价为点的数量,在新图中求出最长链即可
6.NOIP2021 国庆集训 雅礼联考 情报中心
solution:
设
b
i
t
s
e
t
bitset
bitset
f
i
,
j
f_{i,j}
fi,j表示
i
i
i号点走
j
j
j步能到的点的集合
b
f
s
bfs
bfs得到f,然后求并集
code
7.NOIP2021 冲刺集训 长乐OI Day 10 选点游戏
sol:
进行dfs,每次每个联通块的起始点一定是dfn最小的点。我们记这种点记为贡献节点。先一遍dfs,找到图中所有的贡献节点打上标记。然后我们在考虑选点建图对于贡献节点的变化。首先,对于原来就是的点而言,他如果存下那么它还是贡献节点,这是显然的,这部分的点的个数我们可以用前缀和计算。所以我们现在考虑原来不是的点,我们知道如果一个点如果是贡献节点,那么它的dfn一定是这个联通块最小的点。并且这些点一定会在区间 [ l , l + k − 1 ] , [ r − k + 1 , r ] [l,l+k-1],[r-k+1,r] [l,l+k−1],[r−k+1,r]上,我们就可以直接对于这两个区间的点进行dfs,看周围的点有没有dfn比它小的,如果没有就是贡献节点了,然后用答案就是贡献节点个数
8.P2738 篱笆回路Fence Loops
sol:
这种题我是真不想写题目意思很简单吧,就是建图找最小环,但是问题在于如何建图,直接按题目意思来吗?好像不行,我们不妨先建单向边,把边当做点(两个),用g来记录左右,就行了。
9.CF1000E We Need More Bosses
sol:
口胡谁都会对吧?缩点后跑树的直径就没了
10.经典图论
sol:
区间最小生成树,用线段树维护区间信息即区间最小生成树即可,运用类似归并的思想
code
11.燃烧的火焰
sol:
先求出每个燃烧点到每个点的距离然后求出每个集合是否符合要求
code
12.集合划分
sol:
把 g c d ≠ 1 gcd\not=1 gcd=1的归于一个集合,所以可以把 g c d ≠ 1 gcd\not=1 gcd=1的数两两建边,然后统计连通块个数cnt,答案就是 2 c n t − 2 2^{cnt}-2 2cnt−2,可以对于每个 a i a_i ai,枚举其约数进行建边。枚举约数时考虑枚举质数的倍数进行提高效率
13.[杭二集训 西⽐拉先知系统]
大致题意:一个无向图,每次操作可以使一个点加上一个值,加的同时与他相邻的节点也会受影响,每次询问求单点的值
sol:
如果暴力修改,一张菊花图就直接卡没了,考虑分治。令
k
=
n
k=\sqrt n
k=n
,统计每个点的度,对于修改而言只需要修改自己以及周围度大于k的点。然后对于查询,若度数大于k,就输出它的权值,否则输出权值以及周围的权值之和。
code
14.P2783 有机化学之神偶尔会作弊
sol:
直接缩点然后求树上两点之间距离就没了
15.CF757 Feam Rocket Rises Again
sol:
建立最短路DAG,然后对树上的点进行讨论,如果一个点的度为1切入点不为s,那么删入点比删自己更优,那么即我删一个点就可以删一条链了,那么把链可以缩成一个点,最后求所有缩完的点的最大点集即可
标签:min,max,sum,sol,solution,贺题,树型,dp 来源: https://blog.csdn.net/qq_43589598/article/details/121766547