BZOJ3289 Mato的文件管理

区间逆序对查询。妙蛙

莫队\(O(n^{1.5}log_2n)\)

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cmath>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
	rg int x=0,f=1;rg char ch=getchar();
	while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int maxn=50001;
int n,m,q,w[maxn],W[maxn],Kuai[maxn];
int t[maxn],ans[maxn],nowans;
struct ques{int l,r,id;}qq[50001];
bool operator < (const ques&a,const ques&b){return Kuai[a.l]==Kuai[b.l]?a.r<b.r:Kuai[a.l]<Kuai[b.l];}
il vd upd(int x,int y){while(x<=m)t[x]+=y,x+=x&-x;}
il int query(int r){int ret=0;while(r)ret+=t[r],r-=r&-r;return ret;}
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	n=gi();Kuai[0]=sqrt(n);
	for(rg int i=1;i<=n;++i)Kuai[i]=(i-1)/Kuai[0];
	for(rg int i=1;i<=n;++i)w[i]=W[i]=gi();
	std::sort(W+1,W+n+1);m=std::unique(W+1,W+n+1)-W-1;
	for(rg int i=1;i<=n;++i)w[i]=std::lower_bound(W+1,W+m+1,w[i])-W;
	q=gi();
	for(rg int i=1;i<=q;++i)qq[i].l=gi(),qq[i].r=gi(),qq[i].id=i;
	std::sort(qq+1,qq+q+1);
	int l,r;l=r=1,nowans=0,upd(w[1],1);
	for(rg int i=1;i<=q;++i){
		while(l<qq[i].l)nowans-=query(w[l]-1),upd(w[l],-1),++l;
		while(l>qq[i].l)--l,nowans+=query(w[l]-1),upd(w[l],1);
		while(r>qq[i].r)nowans-=query(m)-query(w[r]),upd(w[r],-1),--r;
		while(r<qq[i].r)++r,nowans+=query(m)-query(w[r]),upd(w[r],1);
		ans[qq[i].id]=nowans;
	}
	for(rg int i=1;i<=q;++i)printf("%d\n",ans[i]);
	return 0;
}
posted @ 2018-01-06 11:58  菜狗xzz  阅读(167)  评论(0编辑  收藏  举报