[bzoj3289]Mato的文件管理
莫队,再用树状数组/线段树维护一下逆序对数即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 50005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 int K,n,m,a[N],b[N],ans[N],f[N<<2]; 8 struct ji{ 9 int x,y,id; 10 bool operator < (const ji &k)const{ 11 return (x/K<k.x/K)||(x/K==k.x/K)&&(y<k.y); 12 } 13 }q[N]; 14 void update(int k,int l,int r,int x,int y){ 15 if (l==r){ 16 f[k]+=y; 17 return; 18 } 19 if (x<=mid)update(L,l,mid,x,y); 20 else update(R,mid+1,r,x,y); 21 f[k]=f[L]+f[R]; 22 } 23 int query(int k,int l,int r,int x,int y){ 24 if ((l>y)||(x>r))return 0; 25 if ((x<=l)&&(r<=y))return f[k]; 26 return query(L,l,mid,x,y)+query(R,mid+1,r,x,y); 27 } 28 void up(int k,int p1,int p2){ 29 update(1,1,n,a[k],p1); 30 if (p2)ans[0]+=p1*query(1,1,n,a[k]+1,n); 31 else ans[0]+=p1*query(1,1,n,1,a[k]-1); 32 } 33 int main(){ 34 scanf("%d",&n); 35 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 36 memcpy(b,a,sizeof(b)); 37 sort(b+1,b+n+1); 38 for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+n+1,a[i])-b; 39 scanf("%d",&m); 40 for(int i=1;i<=m;i++){ 41 scanf("%d%d",&q[i].x,&q[i].y); 42 q[i].id=i; 43 } 44 K=(int)sqrt(n); 45 sort(q+1,q+m+1); 46 int l=1,r=0; 47 for(int i=1;i<=m;i++){ 48 while (q[i].x<l)up(--l,1,0); 49 while (r<q[i].y)up(++r,1,1); 50 while (l<q[i].x)up(l++,-1,0); 51 while (q[i].y<r)up(r--,-1,1); 52 ans[q[i].id]=ans[0]; 53 } 54 for(int i=1;i<=m;i++)printf("%d\n",ans[i]); 55 }