莫队+树状数组,需要离散化
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std ;
int n,m,sn;
int a[50010],b[50010],lens;
typedef struct NODE{
int s,t;
int id,ids,ans;
}N;
N map[50010];
int tree[65536],maxlen=1;
void init (){
cin >>n;
sn=sqrt (n);
int i;
for (i=1;i<=n;i++){
scanf ("%d",&a[i]);
b[i]=a[i];
}
cin >>m;
for (i=1;i<=m;i++){
scanf ("%d %d",&map[i].s,&map[i].t);
map[i].id=map[i].s/sn;
if (map[i].id>sn) map[i].id=sn;
map[i].ids=i;
}
}
int lowbit (int x){
return x&(-x);
}
void add_it (int x,int zf){
int now=x;
while (now<=maxlen) {
tree[now]+=zf;
now+=lowbit (now);
}
}
int sum (int x){
int cnt=0;
while (x){
cnt+=tree[x];
x-=lowbit (x);
}
return cnt;
}
int add_head (int x,int zf){
int add=sum(a[x]-1);
add_it (a[x],zf);
return zf*add;
}
int add_tail (int x,int zf){
int add=sum(maxlen)-sum(a[x]);
add_it (a[x],zf);
return zf*add;
}
void work (){
int i;
int S=1,T=0;
int ans=0;
for (i=1;i<=m;i++){
while (S<map[i].s){
ans+=add_head (S,-1);
S++;
}
while (S>map[i].s){
S--;
ans+=add_head (S,1);
}
while (T<map[i].t){
T++;
ans+=add_tail (T,1);
}
while (T>map[i].t){
ans+=add_tail (T,-1);
T--;
}
map[i].ans=ans;
}
}
int cmp (const void *a,const void *b){
N x=*(N *)a,y=*(N *)b;
if (x.id > y.id) return 1;
else {
if (x.id==y.id) {
if (x.t > y.t) return 1;
else return -1;
}
else return -1;
}
}
int cmp1 (const void *a,const void *b){
return ((N *)a)->ids>((N *)b)->ids ? 1 : -1;
}
int main (){
init ();
int i;
qsort (map+1,m,sizeof(map[1]),cmp);
sort (b+1,b+1+n);
lens=unique (b+1,b+n+1)-b-1;
for (i=1;i<=n;i++) a[i]=lower_bound (b+1,b+1+lens,a[i])-b;
while (maxlen<map[m].t) maxlen<<=1;
work ();
qsort (map+1,m,sizeof (map[i]),cmp1);
for (i=1;i<=m;i++){
printf ("%d\n",map[i].ans);
}
return 0;
}