time limit: per test2 seconds
memory limit :per test256 megabytes
standard input
standard output
Description
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≤n≤2⋅105,−109≤x≤109)
(
1
≤
n
≤
2
⋅
10
5
,
−
10
9
≤
x
≤
10
9
)
The second line contains
n integers a1,a2,…,an
(−109≤ai≤109)
(
−
10
9
≤
a
i
≤
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
input1
5 3
1 2 3 4 5
output1
6 5 4 0 0 0
input2
2 6
-5 9
output2
1 2 0
input3
6 99
-1 -1 -1 -1 -1 -1
output3
0 6 5 4 3 2 1
题目大意
n个数组成的数列,一个参数x,对于每一个k
(0≤k≤n)
(
0
≤
k
≤
n
)
,输出只有k个数小于x的区间个数
啊?将小于x的变成1,其余变成0,设其前缀和为s[i],对于一个区间[l,r]小于x的个数为 s[r]−s[l−1] s [ r ] − s [ l − 1 ] ,那么存下s[i]=k的个数f[k],然后用FFT即可
codes
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
#define mo 2748779069441
#define N 524288
using namespace std;
ll w[N],a[N],y[N],b[N],wn;
int n,x;
ll qmul(ll a,ll b){
ll s=(long double)a/mo*b;s=a*b-s*mo;
if(s<0)s+=mo;if(s>=mo)s-=mo;return s;
}
ll qpow(ll a,ll i){
ll r=1;for(;i;i>>=1,a=qmul(a,a))if(i&1)r=qmul(a,r);return r;
}
void fft(ll *a,int sig){
ll ny=qpow(N,mo-2);
for(int i=0;i<N;i++)y[i]=a[i];
for(int i=0,p=0;i<N;i++){
if(i<p)swap(y[i],y[p]);
for(int j=N>>1;(p^=j)<j;j>>=1);
}
for(int hf=1,m=2;m<=N;hf=m,m<<=1)for(int i=0;i<hf;i++){
ll W=w[(m+i*sig)%m*(N/m)];
for(int j=i;j<N;j+=m){
int k=j+hf;ll u=y[j],v=qmul(y[k],W);
y[j]=(u+v)%mo;y[k]=(u+mo-v)%mo;
}
}
for(int i=0;i<N;i++)a[i]=y[i];
if(sig<0)for(int i=0;i<N;i++)a[i]=qmul(a[i],ny);
}
int main(){
scanf("%d %d",&n,&x);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);b[0]=1;
for(int i=1;i<=n;i++)++b[a[i]=(a[i]<x)+a[i-1]];
for(int i=0;i<=n;i++)a[n-i]=b[i];
w[0]=1;wn=qpow(3,(mo-1)/N);for(int i=1;i<N;i++)w[i]=qmul(w[i-1],wn);
fft(a,1);fft(b,1);for(int i=0;i<N;i++)a[i]=qmul(a[i],b[i]);fft(a,-1);
printf("%I64d",(a[n]-n)/2);for(int i=n+1;i<=n+n;i++)printf(" %I64d",a[i]);
return 0;
}