传送门biu~
莫队处理询问,树状数组维护逆序对。
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
#define N 50005
using namespace std;
int n,m,Max,ans,blocksize,a[N],b[N],block[N],tree[N];
struct Ques{int l,r,id,ans;}q[N];
inline bool cmp(Ques a,Ques b){return block[a.l]<block[b.l] || block[a.l]==block[b.l] && a.r<b.r;}
inline bool cmp_id(Ques a,Ques b){return a.id<b.id;}
inline void add(int x,int num){for(int i=x;i<=Max;i+=lowbit(i)) tree[i]+=num;}
inline int search(int x){int re=0;for(int i=x;i;i-=lowbit(i))re+=tree[i]; return re;}
inline int search(int l,int r){return search(r)-search(l-1);}
int main(){
scanf("%d",&n);blocksize=sqrt(n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i],block[i]=(i-1)/blocksize+1;
sort(b+1,b+n+1); Max=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+Max+1,a[i])-b;
scanf("%d",&m);
for(int i=1;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
sort(q+1,q+m+1,cmp);
int l=1,r=0;
for(int i=1;i<=m;++i){
while(q[i].r>r){
++r;
ans+=search(a[r]+1,Max);
add(a[r],1);
}
while(q[i].l<l){
--l;
ans+=search(1,a[l]-1);
add(a[l],1);
}
while(q[i].r<r){
ans-=search(a[r]+1,Max);
add(a[r],-1);
--r;
}
while(q[i].l>l){
ans-=search(1,a[l]-1);
add(a[l],-1);
++l;
}
q[i].ans=ans;
}
sort(q+1,q+m+1,cmp_id);
for(int i=1;i<=m;++i) printf("%d\n",q[i].ans);
return 0;
}