题解:莫队,离散化后用树状数组维护
/**************************************************************
Problem: 3289
User: ws_zzyer
Language: C++
Result: Accepted
Time:4904 ms
Memory:2856 kb
****************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50009;
const int SIZ=300;
int n,m;
int a[maxn];
int b[maxn],nn;
int c[maxn];
inline int lowbit(int x){
return x&(-x);
}
void Addp(int x,int val){
while(x<=nn){
c[x]+=val;
x+=lowbit(x);
}
}
int Querysum(int x){
int ret=0;
while(x){
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
int p[maxn];
int qx[maxn],qy[maxn];
long long ans[maxn];
bool cmp(const int &rhs1,const int &rhs2){
if((qx[rhs1]-1)/SIZ==(qx[rhs2]-1)/SIZ){
return qy[rhs1]<qy[rhs2];
}else{
return qx[rhs1]<qx[rhs2];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
int x;scanf("%d",&x);
a[i]=b[i]=x;
}
sort(b+1,b+1+n);
nn=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+nn,a[i])-b;
scanf("%d",&m);
for(int i=1;i<=m;++i){
scanf("%d%d",&qx[i],&qy[i]);
}
for(int i=1;i<=m;++i)p[i]=i;
sort(p+1,p+1+m,cmp);
int l=1,r=0;
long long nowans=0;
for(int i=1;i<=m;++i){
int t=p[i];
int x=qx[t];
int y=qy[t];
while(l<x){
Addp(a[l],-1);
nowans-=Querysum(a[l]-1);
++l;
}
while(l>x){
--l;
Addp(a[l],1);
nowans+=Querysum(a[l]-1);
}
while(r<y){
++r;
Addp(a[r],1);
nowans+=(r-l+1-Querysum(a[r]));
}
while(r>y){
Addp(a[r],-1);
nowans-=(r-l-Querysum(a[r]));
--r;
}
// cout<<l<<‘ ‘<<r<<endl;
ans[t]=nowans;
}
for(int i=1;i<=m;++i)printf("%lld\n",ans[i]);
return 0;
}