序列计数(count)
题目描述
长度为n+1的序列A,其中的每个数都是不大于n的正整数,且n以内每个正整数至少出现一次。
对于每一个正整数k=1,…,n+1,求出的本质不同的长度为k的子序列(不一定要连续)的数量。对109+7取模。
输入格式
第一行一个正整数n。
第二行n+1个正整数A1…An+1,描述序列A。
输出格式
n+1行,对于第i行,输出一个整数表示长度为i的本质不同子序列的数量,对10^9+7取模。
样例
input1
3
1 2 1 3
output1
3
5
4
1
explanation
长度为1的子序列有3个:1 ,2 ,3。
长度为2的子序列有5个:11 ,12 ,13,21,23。
长度为3的子序列有4个:121 ,123 ,113,213。
长度为4的子序列有1个:1213。
input2
见样例 ex_count2.in。
output2
见样例 ex_count2.out。
数据范围和约定
对于20%的数据,n≤20。
对于40%的数据,n≤2000。
对于额外20%的数据,保证A中相同的数一定相邻。
对于100%的数据,n≤100000,1≤Ai≤n。
时间限制:1s 空间限制:512MB
真的没有时间和心情写博客所以就把考试写的思路发上来了所以语无伦次我自己也有些看不懂非常抱歉请求谅解
10
5 2 6 8 4 3 9 1 4 7 10
left=5
right=9
重复的元素记为rix
考虑left和right出现在同一位置的可能性,这样就本质相同了,此时应减去其情况数
设当前选i个,rix出现在第j位上。
先考虑左边的那个rix
a1 a2 a3 … aj-1 rix aj+1 … ai
则a1~aj-1都是rix之前的,aj+1到ai都是rix之后的
情况数为
C
(
l
e
f
−
1
,
j
−
1
)
∗
C
(
i
−
l
e
f
,
i
−
j
)
C(lef-1,j-1)*C(i-lef,i-j)
C(lef−1,j−1)∗C(i−lef,i−j)
考虑lef,rig两种情况中重复的选择情况数为:
C
(
l
e
f
−
1
,
j
−
1
)
∗
C
(
N
+
1
−
r
i
g
,
i
−
j
)
,
C(lef-1,j-1)*C(N+1-rig,i-j),
C(lef−1,j−1)∗C(N+1−rig,i−j),
j∈[1,i]且满足lef-1>=j-1,N+1-rig>=i-j,
所以j∈[max(1,i+rig-N-1),min(i,lef)]
故答案为:
C
(
N
+
1
,
i
)
−
Σ
C
(
l
e
f
−
1
,
j
−
1
)
∗
C
(
N
+
1
−
r
i
g
,
i
−
j
)
(
j
的
范
围
如
上
)
C(N+1,i)-ΣC(lef-1,j-1)*C(N+1-rig,i-j)(j的范围如上)
C(N+1,i)−ΣC(lef−1,j−1)∗C(N+1−rig,i−j)(j的范围如上)
这个方法对所有i∈[1,N+1]成立
可是这个做法是O(N^2)的
肯定过不了
肯定会被大佬嘲笑
所以要么优化要么换一个方法
反正答案应该是O(N)的吧
优化就是一个思路:
考虑能不能把那个Σ变成O(1)的
怎么变成O(1)的呢?
1.考虑通过神奇的数学公式变成O(1)的
2.考虑有没有递推关系
主 要 是 把 减 数 那 一 坨 Σ 化 简 , 发 现 C ( l e f − 1 , j − 1 ) 可 以 提 出 来 , 所 以 Σ C ( l e f − 1 , j − 1 ) ∗ C ( N + 1 − r i g , i − j ) = C ( l e f − 1 , j − 1 ) ∗ Σ C ( N + 1 − r i g , i − j ) 。 其 中 i − j 的 范 围 为 ( i − j ) ∈ [ i − m i n ( i , l e f ) , i − m a x ( 1 , i + r i g − N − 1 ) ] 。 主要是把减数那一坨Σ化简,发现C(lef-1,j-1)可以提出来,所以ΣC(lef-1,j-1)*C(N+1-rig,i-j)=C(lef-1,j-1)*ΣC(N+1-rig,i-j)。其中i-j的范围为(i-j)∈[i-min(i,lef),i-max(1,i+rig-N-1)]。 主要是把减数那一坨Σ化简,发现C(lef−1,j−1)可以提出来,所以ΣC(lef−1,j−1)∗C(N+1−rig,i−j)=C(lef−1,j−1)∗ΣC(N+1−rig,i−j)。其中i−j的范围为(i−j)∈[i−min(i,lef),i−max(1,i+rig−N−1)]。
我们再来化简ΣC(N+1-rig,i-j)。
先把类分开来讨论:
①
1
<
=
i
+
r
i
g
−
N
−
1
时
:
即
i
>
=
N
−
r
i
g
+
2
时
:
① 1<=i+rig-N-1时:即i>=N-rig+2时:
①1<=i+rig−N−1时:即i>=N−rig+2时:
Ⅰ
.
i
<
=
l
e
f
时
,
i
−
j
∈
[
0
,
N
+
1
−
r
i
g
]
,
Σ
C
(
N
+
1
−
r
i
g
,
i
−
j
)
就
可
以
很
偷
税
地
二
项
式
定
理
,
此
时
原
式
=
C
(
l
e
f
−
1
,
j
−
1
)
∗
(
2
(
N
+
1
−
r
i
g
)
)
Ⅰ. i<=lef 时,i-j ∈[0,N+1-rig] , ΣC(N+1-rig,i-j) 就可以很偷税地二项式定理,此时原式=C(lef-1,j-1)*(2^(N+1-rig))
Ⅰ.i<=lef时,i−j∈[0,N+1−rig],ΣC(N+1−rig,i−j)就可以很偷税地二项式定理,此时原式=C(lef−1,j−1)∗(2(N+1−rig))
Ⅱ
.
i
>
l
e
f
时
,
i
−
j
∈
[
i
−
l
e
f
,
N
+
1
−
r
i
g
]
,
可
以
先
求
一
个
前
缀
和
,
再
用
二
项
式
定
理
减
去
这
个
前
缀
和
,
此
时
原
式
=
C
(
l
e
f
−
1
,
j
−
1
)
∗
(
2
(
N
+
1
−
r
i
g
)
−
(
C
(
N
+
1
−
r
i
g
,
0
)
+
C
(
N
+
1
−
r
i
g
,
1
)
+
.
.
.
+
C
(
N
+
1
−
r
i
g
,
i
−
l
e
f
)
)
)
Ⅱ. i>lef 时,i-j ∈[i-lef,N+1-rig],可以先求一个前缀和,再用二项式定理减去这个前缀和,此时原式=C(lef-1,j-1)*(2^(N+1-rig)-(C(N+1-rig,0)+C(N+1-rig,1)+...+C(N+1-rig,i-lef)))
Ⅱ.i>lef时,i−j∈[i−lef,N+1−rig],可以先求一个前缀和,再用二项式定理减去这个前缀和,此时原式=C(lef−1,j−1)∗(2(N+1−rig)−(C(N+1−rig,0)+C(N+1−rig,1)+...+C(N+1−rig,i−lef)))
然后这两种情况其实可以合并,只需要令下标为负数的前缀和为0即可。
(或者干脆if一下合什么并有神经病)
②i<N-rig+2时:
Ⅰ. i<=lef 时,i-j ∈[0,i-1] , 发现也是前缀和,而且不需要二项式定理。
Ⅱ. i>lef 时,i-j ∈[i-lef,i-1],前缀和也可以解决,而且不需要二项式定理。