[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 }
View Code

 

 

posted @ 2019-08-07 19:55  PYWBKTDA  阅读(126)  评论(0编辑  收藏  举报