[LOJ6077][2017 山东一轮集训 Day7]逆序对
Posted Tan_tan_tann
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LOJ6077][2017 山东一轮集训 Day7]逆序对相关的知识,希望对你有一定的参考价值。
逆序对
题解
首先,看到这道题,应该很容易想到
d
p
dp
dp。
我们将所有的数字从小到大加入,当加入数字
i
i
i时,它有
i
i
i个可选择位置,可能产生
[
0
,
i
−
1
]
[0,i-1]
[0,i−1]个逆序对。
所以容易联想到生成函数,
A
n
s
=
(
∏
i
=
1
n
(
∑
j
=
0
i
−
1
x
j
)
)
[
x
k
]
=
(
∏
i
=
1
n
1
−
x
i
1
−
x
)
[
x
k
]
=
∏
i
=
1
n
(
1
−
x
i
)
(
1
−
x
)
n
Ans=(\\prod_{i=1}^{n}(\\sum_{j=0}^{i-1}x^j))[x^k]=(\\prod_{i=1}^{n}\\frac{1-x^i}{1-x})[x^k]=\\frac{\\prod_{i=1}^{n}(1-x^i)}{(1-x)^n}
Ans=(i=1∏n(j=0∑i−1xj))[xk]=(i=1∏n1−x1−xi)[xk]=(1−x)n∏i=1n(1−xi)
对于分母
1
(
1
−
x
)
n
\\frac{1}{(1-x)^n}
(1−x)n1,它是与
∑
j
=
0
(
j
+
n
−
1
n
−
1
)
x
j
\\sum_{j=0}\\binom{j+n-1}{n-1}x^j
∑j=0(n−1j+n−1)xj等价的。
由于,
1
(
1
−
x
)
n
=
(
1
+
x
+
x
2
+
.
.
.
+
x
n
)
n
\\frac{1}{(1-x)^n}=(1+x+x^2+...+x^n)^n
(1−x)n1=(1+x+x2+...+xn)n,那么对于
x
i
x^i
xi,它的次数可以被划分成
n
n
n段,对应每一种乘到它的路径,划分数可以用隔板法进行理解,我们最后有
i
i
i个空位与
n
−
1
n-1
n−1个隔板,相当于我们要从最开始的
i
+
n
−
1
i+n-1
i+n−1个元素中选出
n
−
1
n-1
n−1个隔板,系数为
(
j
+
n
−
1
n
−
1
)
\\binom{j+n-1}{n-1}
(n−1j+n−1)。
而对于我们的分子,相当于我们有
n
n
n个价值分别为
1
,
2
,
3
,
.
.
.
,
n
1,2,3,...,n
1,2,3,...,n的物品,我们要选出一些物品,使他们的价值总和为
i
i
i,如果选择的物品数量为奇数,贡献就为
−
1
-1
−1,数量为偶数贡献就为
1
1
1,求所有方法的贡献和。
由于所有物品的价值不相同,所以我们选择的物品数量是
n
\\sqrt{n}
n级别的,我们可以用
d
p
dp
dp来进行处理。
我们令
d
p
i
,
j
dp_{i,j}
dpi,j表示已经选择了
i
i
i个物品,它们的总和为
j
j
j。
d
p
dp
dp的转移我们可以考虑采取那种一层一层消的思路,转移有两类:
- 让已经选择了的所有的物品的权值加 1 1 1。
- 在上一个操作的基础上再加入一个权值为 1 1 1的物品。
容易得到状态转移方程式,
d
p
i
,
j
=
d
p
i
−
1
,
j
−
i
+
d
p
i
,
j
−
i
−
[
j
>
n
]
d
p
i
−
1
,
j
−
n
−
1
dp_{i,j}=dp_{i-1,j-i}+dp_{i,j-i}-[j>n]dp_{i-1,j-n-1}
dpi,j=dpi−1,j−i+dpi,j−i−[j>n]dpi−1,j−n−1
后面减去
d
p
i
−
1
,
j
−
n
dp_{i-1,j-n}
dpi−1,j−n是为了排除选择物品的价值超过
n
n
n的情况,由于我们一次只会加一,所以价值超过
n
n
n的物体都是从合法状态转移而来的,价值刚好为
n
+
1
n+1
n+1,将其减去剩下的都是合法的了。
然后再将两部分合并在一起就可以得到答案了,由于我们求的只是
x
k
x^k
xk这一项的系数,完全没必要通过
N
T
T
NTT
NTT来进行合并,直接乘在一起即可,答案即为
A
n
s
=
∑
i
=
0
n
(
−
1
)
i
∑
j
=
0
k
(
k
−
j
+
n
−
1
n
−
1
)
d
p
i
,
j
Ans=\\sum_{i=0}^{n}(-1)^i\\sum_{j=0}^{k}\\binom{k-j+n-1}{n-1}dp_{i,j}
Ans=i=0∑n(−1)ij=0∑k(n−1k−j+n−1)dpi,j
时间复杂度 O ( k l o g k + n ) O\\left(klog\\,k+n\\right) O(klogk+n)
源码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200005
#define MAXM 100005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
loj6102 「2017 山东二轮集训 Day1」第三题
Loj #6142. 「2017 山东三轮集训 Day6」A