Codeforces Round #488 by NEAR (Div. 1)
题目链接:
CF993E Nikita and Order Statistics
Nikita likes tasks on order statistics, for example, he can easily find the $k$-th number in increasing order on a segment of an array. But now Nikita wonders how many segments of an array there are such that a given number $x$ is the $k$-th number in increasing order on this segment. In other words, you should find the number of segments of a given array such that there are exactly $k$ numbers of this segment which are less than $x$.
Nikita wants to get answer for this question for each $k$ from $0$ to $n$, where $n$ is the size of the array.
Input
The first line contains two integers $n$ and $x (1 \le n \le 2 \cdot 10^5, -10^9 \le x \le 10^9)$.
The second line contains $n$ integers $a_1,a_2,…,a_n (-10^9 \le a_i \le 10^9)$ — the given array.
Output
Print $n+1$ integers, where the $i$-th number is the answer for Nikita’s question for $k=i−1$.
Examples
input
5 3 1 2 3 4 5
output
6 5 4 0 0 0
input
2 6 -5 9
output
1 2 0
input
6 99 -1 -1 -1 -1 -1 -1
output
0 6 5 4 3 2 1
Solution
题意
给定长度为 $n$ 的数组,对于 $k \in [0, n]$,求有多少个区间满足区间内恰好有 $k$ 个数比 $x$ 小。
题解
FFT
首先,对于数组中的每一个数,如果比 $x$ 小,那么把这个数置为 $1$,否则置为 $0$。然后求该数组的前缀和 $s$。
设 $f[i]$ 表示前缀和等于 $i$ 的个数。那么 $ans[k] = \sum_{i=k}^nf[i]f[i-k] = \sum_{i=k}^nf[i]f[n-(n+k-i)] = \sum_{i+j=n+k}f[i]f[n-j]$。
令 $g[i] = f[n - i]$,则 $ans[k] = \sum_{i+j=n+k}f[i]g[j]$。
问题就转化为求 $f$ 与 $g$ 的卷积。
注意 $k = 0$ 的情况要特判。此时会有 $n + 1$ 次自己和自己算到一起,也就是空串的情况。所以要对 $ans[0]$ 减去 $n + 1$。减完后还要除以 $2$,因为 $k \neq 0$ 时,由于 $s$ 单调不减,因此 $s[i] \ge s[i - k]$。此时一定保证区间的左端点在前,右端点在后。而 $k = 0$ 时,不能保证左端点一定在前,右端点一定在后,所以要除以 $2$。
Code
1 |
|