题解:莫队,离散化后用树状数组维护
/************************************************************** 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; }