CF1504C - Balance the Bits
p
r
o
b
l
e
m
:
problem:
problem:
给出一个长度为
n
n
n 的
01
01
01 序列
S
S
S,要求构造两个长度为
n
n
n 的合法括号序列
a
,
b
a,b
a,b并满足:
{
a
i
=
b
i
,
S
i
=
1
a
i
≠
b
i
,
S
i
=
0
\left\{ \begin{aligned} a_i=b_i&,S_i=1\\ a_i\neq b_i&,S_i=0 \end{aligned} \right.
{ai=biai=bi,Si=1,Si=0
s
o
l
u
t
i
o
n
:
solution:
solution:
设
S
i
=
0
S_i=0
Si=0 数量为
k
0
k_0
k0,
S
i
=
1
S_i=1
Si=1 数量为
k
1
k_1
k1。首先,因为
S
i
=
0
S_i=0
Si=0 的部分开闭括号的数量在
a
,
b
a,b
a,b 中正好互换,并且
S
i
=
1
S_i=1
Si=1 的部分在
a
,
b
a,b
a,b 的左右括号情况相同,所以在构造的括号序列中
S
i
=
0
S_i=0
Si=0 的部分左右括号的数量显然要相等才能保证两个序列都合法,所以
k
0
k_0
k0 和
k
1
k_1
k1 都需要为偶数并且要保证序列
S
S
S 的头尾都不能是
0
0
0 才会存在方案。
接着我们使前 k 1 2 \frac{k_1}{2} 2k1 个 S i = 0 S_i=0 Si=0 的位置设为左括号,剩余一半为右括号,而对于 S i = 1 S_i=1 Si=1 的部分我们陆续使用左右括号构造即可
这里可以用一种直观的方式来证明上述方案的正确性,想象在一个二维坐标系上,其中 x , y x,y x,y 轴分别用来展现序列 a , b a,b a,b 的两个括号序列,初始坐标为 ( 0 , 0 ) (0,0) (0,0)
- 1. 1. 1.当 S i = 1 S_i=1 Si=1 并且 a i = a_i= ai=‘(’ 时, x = x + 1 , y = y + 1 x=x+1,y=y+1 x=x+1,y=y+1
- 2. 2. 2.当 S i = 0 S_i=0 Si=0 并且 a i = a_i= ai=‘(’ 时, x = x + 1 , y = y − 1 x=x+1,y=y-1 x=x+1,y=y−1
- 3. 3. 3.当 S i = 1 S_i=1 Si=1 并且 a i = a_i= ai=‘)’ 时, x = x − 1 , y = y − 1 x=x-1,y=y-1 x=x−1,y=y−1
- 4. 4. 4.当 S i = 0 S_i=0 Si=0 并且 a i = a_i= ai=‘)’ 时, x = x − 1 , y = y + 1 x=x-1,y=y+1 x=x−1,y=y+1
显然我们的目标就是在 n n n 次操作后回到坐标原点,并且期间不能超过 x , y x,y x,y 轴,显然操作 2 , 3 , 4 2,3,4 2,3,4 都是不太利于我们达到目标的,所以我们尽量就是在靠近直线 y = x y=x y=x 上进行移动,以 2 , 4 2,4 2,4 操作互相抵消,最后以操作 4 4 4 回到原点,那么就是上述构造方法了。
CF1542E1 - Abnormal Permutation Pairs (easy version)
p
r
o
b
l
e
m
:
problem:
problem:
计算长度为
n
(
n
<
=
50
)
n(n<=50)
n(n<=50) 的全排列序对
(
p
,
q
)
(p,q)
(p,q) 满足:
p
p
p 的字典序小于
q
q
q,并且
p
p
p 的逆序对数大于
q
q
q 的对数给出的模数
m
o
d
mod
mod 取模的结果
s
o
l
u
t
i
o
n
:
solution:
solution:
首先从字典序大小入手,如果
p
p
p 的字典小于
q
q
q,这里我们把它分为两种情况:
{
1
.
p
1
<
q
1
2
.
存
在
下
标
i
满
足
p
i
<
q
i
,
且
之
前
的
元
素
都
相
等
\left\{ \begin{aligned} 1&.p_1<q_1\\2&.存在下标i满足 p_i<q_i,且之前的元素都相等 \end{aligned} \right.
{12.p1<q1.存在下标i满足pi<qi,且之前的元素都相等 那么显然我们找到了入手的方向,我们设
t
i
t_i
ti 为长度为
i
i
i 并且满足
p
1
<
q
1
&
i
n
v
(
p
)
>
i
n
v
(
q
)
p_1<q_1\& inv(p)>inv(q)
p1<q1&inv(p)>inv(q) 的方案数 ,可以发现答案与
t
i
t_i
ti 存在如下关系:
a
n
s
i
=
t
i
+
a
n
s
i
−
1
∗
i
ans_i=t_i+ans_{i-1}*i
ansi=ti+ansi−1∗i :即上述第
2
2
2 种情况我们用
a
n
s
i
−
1
ans_{i-1}
ansi−1 来计算。以
p
1
=
q
1
=
i
p_1=q_1=i
p1=q1=i 为例,显然在序首位置加入相同元素对
p
,
q
p,q
p,q 的逆序对相对数量关系无影响,那么显然答案就是
a
n
s
i
−
1
ans_{i-1}
ansi−1。
同样的对于序首元素为 1 , 2... i − 1 1,2...i-1 1,2...i−1 情况类似,且虽然后面 i − 1 i-1 i−1 个元素与组成 a n s i − 1 ans_{i-1} ansi−1 的序列构成不同,但是他们的绝对大小是一样的,所以情况 2 2 2 的答案可以记作 a n s i − 1 ∗ i ans_{i-1}*i ansi−1∗i。
接着我们要去解决如何计算 t i t_i ti,我们枚举 p 1 = j , q 1 = k p_1=j,q_1=k p1=j,q1=k,那么 i n v ( p ) > i n v ( q ) ⟺ i n v ( p [ 2... i ] ) − i n v ( q [ 2.. i ] ) > k − j ⟺ i n v ( q [ 2.. i ] ) < = i n v ( p [ 2... i ] ) − k + j − 1 inv(p)>inv(q)\iff inv(p[2...i])-inv(q[2..i])>k-j\iff inv(q[2..i])<=inv(p[2...i])-k+j-1 inv(p)>inv(q)⟺inv(p[2...i])−inv(q[2..i])>k−j⟺inv(q[2..i])<=inv(p[2...i])−k+j−1,接着我们设 f ( i , j ) f(i,j) f(i,j) 代表长度为 i i i 的序列逆序对数为 j j j 的排列数量,那么: t i = ∑ j = 1 i ∑ k = j + 1 i ∑ x = 0 i 2 2 + 3 i 2 + 1 f ( i − 1 , x ) ∗ ∑ y = 0 x − k + j − 1 f ( i − 1 , y ) t_i=\sum_{j=1}^i\sum_{k=j+1}^i\sum_{x=0}^{\frac{i^2}2+\frac{3i}2+1}f(i-1,x)*\sum_{y=0}^{x-k+j-1}f(i-1,y) ti=j=1∑ik=j+1∑ix=0∑2i2+23i+1f(i−1,x)∗y=0∑x−k+j−1f(i−1,y)
那么 f ( i , j ) f(i,j) f(i,j) 应该怎么计算呢,我们发现对于一个长度为 i − 1 i-1 i−1 的排列,我们是将 i i i 插入到某一位置,那么显然由于 i i i 的最大性,他在可以插入不同的 i i i 个位置后分别能多出 0 − i − 1 0 - i-1 0−i−1 个逆序数,所以 f ( i , j ) = ∑ m a x ( 0 , j − i + 1 ) < = k < = j f ( i − 1 , k ) f(i,j)=\sum_{max(0,j-i+1)<=k<=j}f(i-1,k) f(i,j)=∑max(0,j−i+1)<=k<=jf(i−1,k)。发现可以用前缀和优化一下,使 s ( i , j ) = ∑ k < = j f ( i , k ) s(i,j)=\sum_{k<=j}f(i,k) s(i,j)=∑k<=jf(i,k),最后总的复杂度为 O ( N 4 ) O(N^4) O(N4)。
i
d
e
a
:
idea:
idea:
一开始在想全排列之间的变换对于逆序对数量的影响,一直没什么想法。这道题的关键其实是想到
p
p
p 的字典序比
q
q
q 小背后的那层意思,然后转换到成更好解决的问题。
CF1542E2 - Abnormal Permutation Pairs (hard version)
p
r
o
b
l
e
m
:
problem:
problem:
计算长度为
n
(
n
<
=
500
)
n(n<=500)
n(n<=500) 的全排列序对
(
p
,
q
)
(p,q)
(p,q) 满足:
p
p
p 的字典序小于
q
q
q,并且
p
p
p 的逆序对数大于
q
q
q 的对数给出的模数
m
o
d
mod
mod 取模的结果
s
o
l
u
t
i
o
n
:
solution:
solution:
相比于 easy versio 这道题的数据范围大了
10
10
10 倍,之前的算法显然很难在做到优化至
O
(
N
3
)
O(N^3)
O(N3),我们需要从换一种更直接的计算方式。我们直接设
f
(
i
,
j
)
f(i,j)
f(i,j) 代表长度为
i
i
i 的排列中,
i
n
v
(
p
)
−
i
n
v
(
q
)
=
j
inv(p)-inv(q)=j
inv(p)−inv(q)=j 的数量来代替计算长度为
i
i
i 的排列中,逆序对为
j
j
j 的数量。这样我们相当于直接从两个排列入手,有助于减去一重循环。
那么我们如何计算 f ( i , j ) f(i,j) f(i,j) 呢?首先很容易得到转移方程: f ( i , j ) = ∑ ∣ k ∣ < i f ( i − 1 , j − k ) ∗ ( i − ∣ k ∣ ) f(i,j)=\sum_{|k|<i}f(i-1,j-k)*(i-|k|) f(i,j)=∑∣k∣<if(i−1,j−k)∗(i−∣k∣),复杂度为 O ( N 4 ) O(N^4) O(N4),显然难以承受。我们需要想想如何去优化这个方程。我们通过分析 f ( i , j ) f(i,j) f(i,j) 的结构(以 i = 4 i=4 i=4 为例):
f ( i , j ) = f ( i − 1 , j − 3 ) × 1 + f ( i − 1 , j − 2 ) × 2 + f ( i − 1 , j − 1 ) × 3 + f ( i − 1 , j ) × 4 + f ( i − 1 , j + 1 ) × 3 + f ( i − 1 , j + 2 ) × 2 + f ( i − 1 , j + 3 ) × 1 f(i,j)=f(i-1,j-3)\times 1+f(i-1,j-2)\times 2+f(i-1,j-1)\times3+f(i-1,j)\times 4+f(i-1,j+1)\times 3+f(i-1,j+2)\times 2+f(i-1,j+3)\times1 f(i,j)=f(i−1,j−3)×1+f(i−1,j−2)×2+f(i−1,j−1)×3+f(i−1,j)×4+f(i−1,j+1)×3+f(i−1,j+2)×2+f(i−1,j+3)×1
f ( i , j + 1 ) = f ( i − 1 , j − 2 ) × 1 + f ( i − 1 , j − 1 ) × 2 + f ( i − 1 , j ) × 3 + f ( i − 1 , j + 1 ) × 4 + f ( i − 1 , j + 2 ) × 3 + f ( i − 1 , j + 3 ) × 2 + f ( i − 1 , j + 4 ) × 1 f(i,j+1)=f(i-1,j-2)\times 1+f(i-1,j-1)\times 2+f(i-1,j)\times3+f(i-1,j+1)\times 4+f(i-1,j+2)\times 3+f(i-1,j+3)\times 2+f(i-1,j+4)\times1 f(i,j+1)=f(i−1,j−2)×1+f(i−1,j−1)×2+f(i−1,j)×3+f(i−1,j+1)×4+f(i−1,j+2)×3+f(i−1,j+3)×2+f(i−1,j+4)×1
f
(
i
,
j
+
1
)
−
f
(
i
,
j
)
=
f
(
i
−
1
,
j
+
4
)
+
f
(
i
−
1
,
j
+
3
)
+
f
(
i
−
1
,
j
+
2
)
+
f
(
i
−
1
,
j
+
1
)
−
f
(
i
−
1
,
j
−
1
)
−
f
(
i
−
1
,
j
−
2
)
−
f
(
i
−
1
,
j
−
3
)
−
f
(
i
−
1
,
j
−
4
)
f(i,j+1)-f(i,j)=f(i-1,j+4)+f(i-1,j+3)+f(i-1,j+2)+f(i-1,j+1)-f(i-1,j-1)-f(i-1,j-2)-f(i-1,j-3)-f(i-1,j-4)
f(i,j+1)−f(i,j)=f(i−1,j+4)+f(i−1,j+3)+f(i−1,j+2)+f(i−1,j+1)−f(i−1,j−1)−f(i−1,j−2)−f(i−1,j−3)−f(i−1,j−4)
⟺
f
(
i
,
j
+
1
)
=
f
(
i
,
j
)
+
(
s
(
i
−
1
,
j
+
4
)
−
s
(
i
−
1
,
j
)
)
−
(
s
(
i
−
1
,
j
)
−
s
(
i
−
1
,
j
−
4
)
)
(
s
(
i
,
j
)
=
∑
k
<
=
j
f
(
i
,
j
)
)
\iff f(i,j+1)=f(i,j)+(s(i-1,j+4)-s(i-1,j))-(s(i-1,j)-s(i-1,j-4)) (s(i,j)=\sum_{k<=j}f(i,j))
⟺f(i,j+1)=f(i,j)+(s(i−1,j+4)−s(i−1,j))−(s(i−1,j)−s(i−1,j−4))(s(i,j)=∑k<=jf(i,j))
显然我们可以在 O ( N 3 ) O(N^3) O(N3) 的时间同时计算 f f f 和 s s s,并且可以发现对于 E 1 E1 E1 中的 t i t_i ti,我们完全可以在计算出 s ( i , j ) s(i,j) s(i,j) 后同时计算: t i = ∑ j = 1 i − 1 ∗ ( s ( i − 1 , ( i − 1 ) ∗ ( i − 2 ) 2 ) − s ( i − 1 , j ) ) ∗ ( i − j ) t_i=\sum_{j=1}^{i-1}*(s(i-1,\frac {(i-1)*(i-2)}2)-s(i-1,j))*(i-j) ti=∑j=1i−1∗(s(i−1,2(i−1)∗(i−2))−s(i−1,j))∗(i−j) ,即枚举 p 1 − q 1 p_1-q_1 p1−q1 的值 j j j,然后显然有 i − j i-j i−j 种这样的情况,最后所有后 i − 1 i-1 i−1 个排列逆序对之差大于 j j j 的都满足。常数小的话复杂度会略小于 O ( 1 e 8 ) O(1e8) O(1e8),而空间复杂度 O ( N 3 ) O(N^3) O(N3) 显然无法适用,我们可以用滚动数组优化掉一维,并且注意由于我们的 j j j 代表 p − q p-q p−q 的逆序对数,所以可能存在负数情况,我们需要加一个偏移值以保证非负。
i
d
e
a
:
idea:
idea:
当转移复杂度过大,而转移方程存在一些共性时,我们可以考虑从一些别的角度与一些技巧进行转移而进一步优化复杂度
复习打卡:
- 2020-07-07
- 2020-07-09
- 2020-07-13
- 2020-08-06