CF993E Nikita and Order Statistics

IX.CF993E Nikita and Order Statistics

首先,一上来就能想到的思路,对于\(< x\)的位置,赋成\(1\);对于\(\geq x\)的位置,赋成\(0\),然后跑前缀和,设为\(sum_x\)。这样子,\(x\)在某个子串\([l,r]\)中的排名就是\(sum_r-sum_{l-1}\)

\(x\)\(sum\)数组中出现了\(cnt_x\)次。则某个\(k\)的答案\(ans_k=\sum_{i=k}^ncnt_i*cnt_{i-k}\)。因为挑选任何一个\(sum=i\)的前缀与任何一个\(sum=i-k\)的前缀,都可以拼成一个\(k\)出来。

遇事不决就翻转。我们设\(f\)表示原本的\(cnt\)\(g\)表示翻转(\(g_x=cnt_{n-x}\))后的\(cnt\)

则现在,\(ans_{n-k}=\sum\limits_{i+j=k}f_i*g_j\)。是卷积的形式,直接FFT!!!

不过有几个注意点:

1.\(sum_0\),即空前缀和,也要计入\(cnt\),不然类似于串\([1,r]\)的就不会被计入。估计只有我一个人才会忘记吧

2.\(ans_0\)要特判,因为某些串你瞎卷卷可能卷出来长度为\(0\)的串。可以直接\(O(n)\)暴力扫一遍即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const double pi=acos(-1);
int n,m,cnt[1<<20],lg,lim=1,h[1<<20],rev[1<<20],sum[1<<20];
struct cp{
	double x,y;
	cp(double u=0,double v=0){x=u,y=v;}
	friend cp operator +(const cp &u,const cp &v){return cp(u.x+v.x,u.y+v.y);}
	friend cp operator -(const cp &u,const cp &v){return cp(u.x-v.x,u.y-v.y);}
	friend cp operator *(const cp &u,const cp &v){return cp(u.x*v.x-u.y*v.y,u.x*v.y+u.y*v.x);}
}f[1<<20],g[1<<20];
void FFT(cp *a,int tp){
	for(int i=0;i<lim;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
	for(int md=1;md<lim;md<<=1){
		cp rt=cp(cos(pi/md),tp*sin(pi/md));
		for(int stp=md<<1,pos=0;pos<lim;pos+=stp){
			cp w=cp(1,0);
			for(int i=0;i<md;i++,w=w*rt){
				cp x=a[pos+i],y=w*a[pos+md+i];
				a[pos+i]=x+y;
				a[pos+md+i]=x-y;
			}
		}
	}
}
int zero(){
	int pos=0,res=0;
	for(int i=1;i<=n;i++){
		if(sum[i]!=sum[i-1])pos=i;
		res+=i-pos;
	}
	return res;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	while(lim<=n*2+1)lim<<=1,lg++;
	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
	cnt[0]++;
	for(int i=1,x;i<=n;i++)scanf("%lld",&x),sum[i]=sum[i-1]+(x<m),cnt[sum[i]]++;
	for(int i=0;i<=n;i++)f[i]=cp(cnt[i],0),g[i]=cp(cnt[n-i],0);
	FFT(f,1),FFT(g,1);
	for(int i=0;i<lim;i++)f[i]=f[i]*g[i];
	FFT(f,-1);
	for(int i=0;i<=n;i++)h[n-i]=(int)(f[i].x/lim+0.5);
	printf("%lld ",zero());
	for(int i=1;i<=n;i++)printf("%lld ",h[i]);
	return 0;
}
posted @ 2020-04-25 11:56  Troverld  阅读(140)  评论(0编辑  收藏  举报