[P6822] [PA2012]Tax
Tag: 建模 \text{Tag: 建模} Tag: 建模
考虑将无向边拆成两条有向边,化边为点。
一种显然的暴力就是将一个点的入边和出边两两建边,边权就是入边出边的边权最大值,但是这样边数是 O ( m 2 ) O(m^2) O(m2) 的。
考虑一个点的所有出边,将其排序,得到边序列
{
e
n
}
\{e_n\}
{en} ,显然的,我们可以将相邻两条边对应的点连边:
e
i
−
1
→
w
e
i
−
w
e
i
−
1
e
i
e
i
→
0
e
i
−
1
\begin{aligned} \large e_{i-1} \xrightarrow{w_{e_i} - w_{e_{i-1}}} e_i\\ \large e_i \xrightarrow{0} e_{i-1} \end{aligned}
ei−1wei−wei−1eiei0ei−1
同时,要实现从入边到出边,可以这样连边:
(
u
,
v
)
→
w
(
u
,
v
)
(
v
,
u
)
\large (u,v)\xrightarrow{w_{(u,v)}} (v, u)
(u,v)w(u,v)(v,u)
然后还要从连接起始点
1
1
1 和终点
n
n
n 。可以这样连边:
1
→
w
(
1
,
u
)
(
1
,
u
)
(
u
,
n
)
→
w
(
u
,
n
)
n
\begin{aligned} \large 1 \xrightarrow{w_{(1,u)}} (1,u)\\ \large (u,n) \xrightarrow{w_{(u,n)}} n \end{aligned}
1w(1,u)(1,u)(u,n)w(u,n)n
[AT5661] [AGC040C] Neither AB nor BA
Tag: 性质, Trick \text{Tag: 性质, Trick} Tag: 性质, Trick
删除操作可以认为是组成一个合法的括号序列,而合法的删除的序列就是任何一组配对的括号在原序列上对应的两个字符拼起来,都不是 BA
或者 AB
。
考虑将序列进行黑白交替染色,比如
n
=
6
n=6
n=6 的时候就是 bwbwbw
。那么每一组括号都是 bw
或者 wb
,而不是 bb
或者 ww
。
接下来将黑色位置的
B
,
A
B,A
B,A 反转,那么限制就变成了不是 AA
或者 BB
。
接下来问题就是变成了 A , B A,B A,B 数量均没有超过 n 2 \frac{n}{2} 2n 的序列个数,考虑容斥即可。
[CF1334E] Divisor Paths
Tag: 性质,数论 \text{Tag: 性质,数论} Tag: 性质,数论
设一条
x
→
y
(
x
∣
y
)
x \rightarrow y ~(x|y)
x→y (x∣y) 的路径为
p
1...
k
p_{1...k}
p1...k 其中
∀
1
≤
i
<
k
,
p
i
<
p
i
+
1
\forall 1\leq i<k, p_i<p_{i+1}
∀1≤i<k,pi<pi+1 ,那么可以得到路径的长度:
w
p
=
∑
i
=
2
k
d
(
p
i
)
−
d
(
p
i
−
1
)
=
d
(
y
)
−
d
(
x
)
w_p=\sum_{i=2}^{k} d(p_i)-d(p_{i-1})=d(y)-d(x)
wp=i=2∑kd(pi)−d(pi−1)=d(y)−d(x)
可以发现路径长度只和起点终点有关。
接下来有一个很显然的性质,从 u u u 到 v v v ,必须是 u → gcd ( u , v ) → v u\rightarrow \gcd(u,v) \rightarrow v u→gcd(u,v)→v 。接下来只需要求两个 u → v ( v ∣ u ) u\rightarrow v~~(v|u) u→v (v∣u) 的路径条数就行了。
考虑
d
=
u
v
d=\frac{u}{v}
d=vu 那么将
d
d
d 分解质因数,即
d
=
∏
i
=
1
k
p
i
c
i
d=\prod_{i=1}^k p_i^{c_i}
d=∏i=1kpici ,那么实际上
u
,
v
u,v
u,v 之间的路径条数可以使用可重排列计算出来:
f
(
u
,
v
)
=
(
∑
i
=
1
k
c
i
c
1
,
c
2
,
⋯
c
k
)
f(u, v) = \binom{\sum_{i=1}^k c_i}{c_1, c_2,\cdots c_k}
f(u,v)=(c1,c2,⋯ck∑i=1kci)
那么最终
u
,
v
u, v
u,v 的答案就是
f
(
gcd
(
u
,
v
)
,
u
)
+
f
(
gcd
(
u
,
v
)
,
v
)
f(\gcd(u,v), u) + f(\gcd(u,v), v)
f(gcd(u,v),u)+f(gcd(u,v),v)。
这里分解质因数可以首先将 d d d 的所有质因数先预处理。
[CF1477B] Nezzar and Binary String
Tag: Trick \text{Tag: Trick} Tag: Trick
正想做比较难,考虑逆向思考,即从第 q q q 天晚上到第 1 1 1 天早上。而我们第 i i i 天晚上就是将 [ l i , r i ] [l_i,r_i] [li,ri] 修改成同一个字符。这个部分可以使用线段树覆盖维护一下,最后再检查是否能将 f f f 修改成 s s s 就行了。
[AT2304] [AGC010C] Cleaning
这题没有 Tag \text{Tag} Tag 。
假如 n = 1 n=1 n=1 ,那么显然无解。
如果 n = 2 n=2 n=2 ,当且仅当 a ( 1 ) = a ( 2 ) a(1)=a(2) a(1)=a(2) 的时候有解。
对于 n > 2 n>2 n>2,选择一个度数最大的点当根节点。
设 f ( u ) f(u) f(u) 表示从节点 u u u 需要向上延伸多少条途径(一次清扫为一条路径)。显然的,对于叶子节点, f ( u ) = a ( u ) f(u)=a(u) f(u)=a(u) 。对于非叶子节点 u u u ,假如 s ( u ) = ∑ v ∈ s o n ( u ) f ( v ) < a ( u ) s(u)=\sum_{v\in \mathrm{son}(u)} f(v) < a(u) s(u)=∑v∈son(u)f(v)<a(u) ,同时,如果 max v ∈ s o n ( u ) f ( v ) > a ( u ) \max_{v\in \mathrm{son}(u)} f(v) > a(u) maxv∈son(u)f(v)>a(u) 也同样是无解的。对于剩下的情况,可以计算出将路径两两配对的数量: s ( u ) − a ( u ) 2 \cfrac{s(u)-a(u)}{2} 2s(u)−a(u) ,那么就能得到向上延伸的路径的条数: f ( u ) = 2 a ( u ) − s ( u ) f(u)=2a(u)-s(u) f(u)=2a(u)−s(u) 。最后特判一下根节点的 f ( u ) = 0 f(u)=0 f(u)=0 ,否则一样是无解的。
[CF1442D] Sum
Tag: 性质, 分治 \text{Tag: 性质, 分治} Tag: 性质, 分治
可以想到一个
O
(
n
3
)
O(n^3)
O(n3) 的
d
p
dp
dp :
f
(
i
,
j
)
=
max
k
=
0
min
{
j
,
t
i
}
{
f
(
i
−
1
,
j
−
k
)
+
∑
x
=
1
k
a
i
,
x
}
f(i,j)=\max_{k=0}^{\min\{j,t_i\}}\{f(i-1,j-k)+\sum_{x=1}^k a_{i,x}\}
f(i,j)=k=0maxmin{j,ti}{f(i−1,j−k)+x=1∑kai,x}
这个东西难以优化。
考虑一个方案 c c c ,其中第 i i i 个序列选择 c i c_i ci 个,假如我们可以选择其中一个序列 a a a 少选择一个,然后另一个序列 b b b 选择多一个,也就是 b c b + 1 ≥ b c a b_{c_b+1} \ge b_{c_a} bcb+1≥bca ,那么可以认为序列 a a a 可以去掉 min ( c a , c b ) \min(c_a, c_b) min(ca,cb) 个,然后 b b b 增加相同个,可以证明这样不会让答案变劣。一顿操作下来,一定有至多一个序列没有选择全部,其余的序列都是要么没选择,要么都选择。
因此可以考虑分治,具体怎么搞就不讲了。
[AT4361] [ARC102B] All Your Paths are Different Lengths
Tag: 构造 \text{Tag: 构造} Tag: 构造
直接放代码:
if (L == 1) { printf("2 1\n1 2 0\n"); return 0; }
while (L) dig[++dig_sz] = (L & 1), L >>= 1;
n = dig_sz;
int t = 1 << (dig_sz - 1);
for (int i = dig_sz - 1; i >= 1; i--) {
if (dig[i]) {
addedge(1, dig_sz - i + 1, t);
t |= (1 << (i - 1));
}
addedge(dig_sz - i, dig_sz - i + 1, 0);
addedge(dig_sz - i, dig_sz - i + 1, (1 << (i - 1)));
}
[AT4169] [ARC100D] Colorful Sequences
Tag: 分类讨论,dp \text{Tag: 分类讨论,dp} Tag: 分类讨论,dp
考虑首先求出所有满足第二个条件的序列的美丽值和,然后减去不满足第一个条件的序列的美丽值和。
满足第二个条件的所有情况的美丽值和可以考虑
A
A
A 的左端点在序列中每一个位置的贡献,有:
A
N
S
=
(
N
−
M
+
1
)
⋅
K
N
−
M
\mathrm{ANS}=(N-M+1) \cdot K^{N-M}
ANS=(N−M+1)⋅KN−M
考虑不满足第一个条件的情况。
如果 A A A 本身就是一个 colorful \text{colorful} colorful 序列,那么就不存在只满足第二个条件的情况。
如果 A A A 不是 colorful \text{colorful} colorful 序列,且存在至少一对重复元素,这时候,任何一对重复元素位置 ( a , b ) (a,b) (a,b) 之间不存在 colorful \text{colorful} colorful 序列,分别找到从左边,从右边第一个重复的位置 l , r l, r l,r ,比如对于 A = { 1 , 2 , 2 , 3 , 2 , 3 } A=\{1,2,2,3,2,3\} A={1,2,2,3,2,3},那么两个找到的两个位置分别是 3 3 3, 4 4 4 。假设这时候序列 A A A 左端点在序列 B B B 的位置 p p p ,那么子段 B 1 ⋯ p + l − 2 B_{1\cdots p+l-2} B1⋯p+l−2, B a + m − r + 1 ⋯ n B_{a+m-r+1\cdots n} Ba+m−r+1⋯n 必须都不满足第一个条件。
考虑
d
p
dp
dp 。设
f
(
i
,
j
)
f(i,j)
f(i,j) 表示当前构建了一个长度为
i
i
i 的序列,其中最长的不重复后缀的长度为
j
j
j ,那么可以得到:
f
(
i
,
j
)
=
f
(
i
−
1
,
j
−
1
)
×
(
K
−
j
+
1
)
+
∑
k
=
j
i
−
1
f
(
i
−
1
,
t
)
f(i,j)=f(i-1,j-1) \times (K - j + 1) + \sum_{k=j}^{i-1} f(i-1,t)
f(i,j)=f(i−1,j−1)×(K−j+1)+k=j∑i−1f(i−1,t)
这个
d
p
dp
dp 可以使用后缀和优化成
O
(
K
2
)
O(K^2)
O(K2) 的。考虑
B
1
⋯
p
+
l
−
2
B_{1 \cdots p+l-2}
B1⋯p+l−2 ,就是当前强制使得前
l
−
1
l-1
l−1 为
A
1
⋯
l
−
1
A_{1\cdots l-1}
A1⋯l−1 翻转过来,即初始化
f
(
0
,
l
−
1
)
=
1
f(0,l-1)=1
f(0,l−1)=1 。对于
B
a
+
m
−
r
+
1
⋯
n
B_{a+m-r+1\cdots n}
Ba+m−r+1⋯n 也是类似的。假设两个部分得到的
d
p
dp
dp 数组分别为
f
,
g
f, g
f,g,那么最终答案就是:
∑
a
=
0
N
−
M
[
∑
i
=
0
K
−
1
f
(
a
,
i
)
]
[
∑
i
=
0
K
−
1
g
(
N
−
M
−
a
,
i
)
]
\sum_{a=0}^{N-M} \left[\sum_{i=0}^{K-1} f(a,i)\right] \left[\sum_{i=0}^{K-1} g(N-M-a,i)\right]
a=0∑N−M[i=0∑K−1f(a,i)][i=0∑K−1g(N−M−a,i)]
考虑没有重复元素,这时候无论
A
A
A 的内容是什么,答案都是一样的。设
f
(
i
,
j
,
0
/
1
)
f(i,j,0/1)
f(i,j,0/1) 表示当前构造了前
i
i
i 项,最长的不重复后缀长度为
j
j
j ,当前是否已经选定了一个位置贡献,那么可以得到:
f
(
i
,
j
,
t
)
=
f
(
i
−
1
,
j
−
1
,
t
)
×
(
K
−
j
+
1
)
+
∑
k
=
j
i
−
1
f
(
i
−
1
,
k
,
t
)
f
(
i
,
j
,
1
)
=
f
(
i
,
j
,
0
)
×
[
j
≥
M
]
\begin{aligned} f(i,j,t) &= f(i-1,j-1,t)\times (K-j+1) + \sum_{k=j}^{i-1} f(i-1,k,t)\\ f(i,j,1) &= f(i,j,0)\times [j \ge M] \end{aligned}
f(i,j,t)f(i,j,1)=f(i−1,j−1,t)×(K−j+1)+k=j∑i−1f(i−1,k,t)=f(i,j,0)×[j≥M]
对于选定的位置,我们令这个位置是
A
1
⋯
m
A_{1\cdots m}
A1⋯m ,具体而言,其对答案的贡献为
g
(
n
,
i
)
K
M
‾
\cfrac{g(n,i)}{K^{\underline{M}}}
KMg(n,i) 。将答案加起来就行了。
[AT4161] [ARC099B] Snuke Numbers
Tag: 找规律 \text{Tag: 找规律} Tag: 找规律
通过打表发现答案都是类似 x 9999 ⋯ 999 ( 1 ≤ x ≤ 9 ) x9999\cdots 999 (1 \leq x \leq 9) x9999⋯999(1≤x≤9) 的。
[AT2567] [ARC074C] RGB Sequence
Tag: dp \text{Tag: dp} Tag: dp
设 f ( i , j , k ) f(i,j,k) f(i,j,k) 表示考虑了前 i i i 个位置,第二个颜色的最后位置为 j j j ,第三个颜色的最后一个位置为 k k k 。
考虑转移,可以得到:
f
(
1
,
0
,
0
)
=
3
f
(
i
+
1
,
j
,
k
)
←
f
(
i
,
j
,
k
)
f
(
i
+
1
,
i
,
k
)
←
f
(
i
,
j
,
k
)
f
(
i
+
1
,
i
,
j
)
←
f
(
i
,
j
,
k
)
\begin{aligned} f(1,0,0) &= 3\\ f(i+1,j,k) &\leftarrow f(i,j,k)\\ f(i+1,i,k) &\leftarrow f(i,j,k)\\ f(i+1,i,j) &\leftarrow f(i,j,k) \end{aligned}
f(1,0,0)f(i+1,j,k)f(i+1,i,k)f(i+1,i,j)=3←f(i,j,k)←f(i,j,k)←f(i,j,k)
考虑限制,考虑在区间的右端点限制,比方对于限制
(
l
,
r
,
2
)
(l,r,2)
(l,r,2) ,需要令
j
<
l
j<l
j<l 或者
k
≥
l
k \ge l
k≥l 的
f
f
f 值为
0
0
0 。
最后的答案显然为:
A
N
S
=
∑
i
=
0
n
−
1
∑
j
=
0
i
f
(
n
,
i
,
j
)
\mathrm{ANS}=\sum_{i=0}^{n-1} \sum_{j=0}^{i} f(n,i,j)
ANS=i=0∑n−1j=0∑if(n,i,j)
[AT4162] [ARC099C] Independence
Tag: Trick \text{Tag: Trick} Tag: Trick
考虑建立补图,如果补图上有边 ( u , v ) (u,v) (u,v) ,那么划分的时候就不能将 u , v u,v u,v 分到同一部分,反之则可以。考虑类似二分图判定的黑白染色,将某个联通快分成两部分,其大小分别为 c 1 , c 2 c_1,c_2 c1,c2 ,如果不能分成两部分,直接输出 − 1 -1 −1 。
考虑可行性
d
p
dp
dp,
f
(
i
,
j
)
f(i,j)
f(i,j) 表示当前考虑了前
i
i
i 个连通块,其中一个部分的大小为
j
j
j ,那么有:
f
(
i
,
j
)
=
f
(
i
−
1
,
j
−
c
i
,
1
)
∨
f
(
i
−
1
,
j
−
c
i
,
2
)
f(i,j)=f(i-1,j-c_{i,1}) \vee f(i-1,j-c_{i,2})
f(i,j)=f(i−1,j−ci,1)∨f(i−1,j−ci,2)
这个东西显然可以用 bitset
维护。
[CF1286D] LCC
Tag: dp,ddp \text{Tag: dp,ddp} Tag: dp,ddp
首先有一个显然的结论,第一次碰撞一定发生在两个起始位置相邻的粒子,因此可以考虑某两个相邻的粒子的碰撞是第一次碰撞,求出其时间和概率,然后再求个和就行了。
假设当前设定
p
,
p
+
1
p,p+1
p,p+1 第一次发生碰撞,其中两个粒子的方向分别为
a
,
b
(
a
,
b
∈
{
0
,
1
}
)
a,b~(a,b\in\{0,1\})
a,b (a,b∈{0,1}) 其中
0
0
0 表示向左,
1
1
1 表示向右,那么可以想到
d
p
dp
dp 求概率。设
f
(
i
,
j
)
f(i,j)
f(i,j) 表示考虑前
i
i
i 个粒子,其中第
i
i
i 个粒子的方向为
j
j
j 其中碰撞事件大于等于
t
(
p
,
a
,
b
)
t(p,a,b)
t(p,a,b),转移比较简单。类似的,设
g
(
i
,
j
)
g(i,j)
g(i,j) 表示考虑后
i
i
i 个粒子,其中第
n
−
i
+
1
n-i+1
n−i+1 粒子的方向为
j
j
j ,其中碰撞时间大于
t
(
p
,
a
,
b
)
t(p,a,b)
t(p,a,b) 。可以想到
A
N
S
(
p
,
a
,
b
)
=
f
(
p
,
a
)
×
g
(
n
−
p
,
b
)
×
t
(
p
,
a
,
b
)
\mathrm{ANS}(p,a,b)=f(p,a)\times g(n-p,b)\times t(p,a,b)
ANS(p,a,b)=f(p,a)×g(n−p,b)×t(p,a,b)
但是很显然这个东西绝对会
T
L
E
\rm{TLE}
TLE 。考虑优化。
发现上面
d
p
dp
dp 转移的过程如果忽略时间的限制,实际上可以认为是矩阵相乘。考虑构建线段树,其中矩阵
A
[
l
,
r
]
,
a
,
b
A_{[l,r],a,b}
A[l,r],a,b 表示第
l
l
l 颗粒子方向为
l
l
l ,第
r
+
1
r+1
r+1 颗粒子的方向为
b
b
b 的概率(除去
r
+
1
r+1
r+1 的概率)。将所有相邻节点信息
(
p
,
a
,
b
)
(p,a,b)
(p,a,b) 按照碰撞事件从大到小排序,考虑一个信息
(
p
,
a
,
b
)
(p,a,b)
(p,a,b) 是第一次碰撞的概率,显然是:
P
(
p
,
a
,
b
)
=
∑
x
=
0
1
∑
y
=
0
1
A
[
1
,
p
−
1
]
,
x
,
a
A
[
p
+
1
,
n
−
1
]
,
b
,
y
P
p
,
a
P
n
,
y
\mathrm{P}(p,a,b)=\sum_{x=0}^{1} \sum_{y=0}^1 A_{[1,p-1],x,a}A_{[p+1,n-1],b,y}P_{p,a} P_{n,y}
P(p,a,b)=x=0∑1y=0∑1A[1,p−1],x,aA[p+1,n−1],b,yPp,aPn,y
将
t
(
p
,
a
,
b
)
×
P
(
p
,
a
,
b
)
t(p,a,b)\times \mathrm{P}(p,a,b)
t(p,a,b)×P(p,a,b) 贡献到答案之后,将
P
p
,
a
P_{p,a}
Pp,a 放到
A
[
p
,
p
]
,
a
,
b
A_{[p,p],a,b}
A[p,p],a,b 就可以了。
[ARC110-D] Binomial Coefficient is Fun
这题没有 T a g \rm{Tag} Tag 。
为了将 ∑ i = 1 N B i ≤ M \sum_{i = 1} ^ N B_i \leq M ∑i=1NBi≤M 变为 ∑ i = 1 N B i = M \sum_{i = 1} ^ N B_i = M ∑i=1NBi=M,增加一个 A N + 1 = 0 A_{N + 1} = 0 AN+1=0 ,然后让 N : = N + 1 N := N + 1 N:=N+1。
令 S = ∑ i = 1 n A i S = \sum_{i = 1} ^ n A_i S=∑i=1nAi。
如果 S > M S > M S>M 则答案为 0 0 0,直接特判。
如果
S
≤
M
S \leq M
S≤M,考虑转化问题。构建一个长度为
S
+
N
S + N
S+N 的序列
p
p
p,其中
p
i
<
p
i
+
1
p_i < p_{i + 1}
pi<pi+1 且
1
≤
p
i
≤
N
+
M
1 \leq p_i \leq N+M
1≤pi≤N+M ,原题显然可以转化为求
p
p
p 序列的个数。那么答案显然为:
A
N
S
=
(
M
+
N
−
1
S
+
N
−
1
)
\mathrm{ANS} = \binom{M + N - 1}{S + N - 1}
ANS=(S+N−1M+N−1)
[ARC112-C] DFS Game
Tag: 分类讨论 \text{Tag: 分类讨论} Tag: 分类讨论
假设现在在节点 u u u ,对于其中一个儿子 v v v ,可以发现,如果节点个数是偶数,那么回到节点 u u u 的时候,先后手不变,反之则变化。设 f ( u ) f(u) f(u) 表示在子树 T u T_u Tu 中先手得分减去后手得分。接下来进行分类讨论。
考虑一个节点 u u u 的儿子 v v v 。
- f ( v ) < 0 f(v) < 0 f(v)<0 且 T v T_v Tv 的节点数量为偶数。
- f ( v ) ≥ 0 f(v) \ge 0 f(v)≥0 且 T v T_v Tv 的节点数量为偶数。
- T v T_v Tv 的节点数量为奇数。
对于 1. 1. 1. ,显然先走完所有这样的节点并不会使答案劣,因此可以先走完所有 1. 1. 1. 节点。对于 2. 2. 2. 节点,先手会选择尽量不走这类节点,因此它会用 3. 3. 3. 节点,这时候一定会选择 f ( v ) f(v) f(v) 最小的,这样可以使回到节点 u u u 的时候,对手能拿到的得分更少。因此可以得到 f ( u ) f(u) f(u) 的计算方式:
首先加入所有 1. 1. 1. 节点的 f ( u ) f(u) f(u) 的相反数。然后将 3. 3. 3. 节点按 f ( u ) f(u) f(u) 从小到大排序,得到序列 l l l ,然后对于第奇数个,加入相反数,对于第偶数个,加入原数,然后根据 ∣ l ∣ |l| ∣l∣ 确定谁是要全部吞下 2. 2. 2. 的倒霉蛋。
最终答案根据 f ( 1 ) f(1) f(1) 确定即可。
[ARC111-D] Orientation
Tag: 性质 \text{Tag: 性质} Tag: 性质
对于第 i i i 条边,如果 c a i = c b i c_{a_i}=c_{b_i} cai=cbi ,那么 a i = b i a_i = b_i ai=bi 必须在同一强连通分量中;如果 c a i > c b i c_{a_i}>c_{b_i} cai>cbi, 那么显然可以定向: a i → b i a_i\rightarrow b_i ai→bi ; c a i < c b i c_{a_i}<c_{b_i} cai<cbi 同理。
对于同一强连通分量的点,将 d f s \rm{dfs} dfs 树定向为外向树,对于非树边,方向定为由深度较大的点到深度较小的点。