【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=3289

 

【题意】

 

    回答若干个询问:[l,r]区间内的逆序对个数。

 

【思路】

 

    莫队算法,BIT维护插入删除。

    使用BIT维护当前指针l,r内的所有的数。考虑转移部分:

        l<q[i].l 删出区间中比a[l]小的数与之构成的逆序对,Q(a[l]-1)

        l>q[i].l l++,添加区间中比a[l]小的数与之构成的逆序对,Q(a[l]-1)

        r>q[i].r 删除区间中比a[r]大的数与之构成的逆序对,r-l+1-Q(a[r])

        r<q[i].r r++,添加区间中比a[r]大的数与之构成的逆序对,r-l-Q(a[r])

        相应修改BIT。

    这一部分比较容易出错 =_=

 

【代码】

 

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #define FOR(a,b,c) for(int a=b;a<=c;a++)
 7 using namespace std;
 8 
 9 typedef long long ll;
10 const int N = 1e5+10;
11 
12 ll read() {
13     char c=getchar();
14     ll f=1,x=0;
15     while(!isdigit(c)) {
16         if(c=='-') f=-1; c=getchar();
17     }
18     while(isdigit(c))
19         x=x*10+c-'0',c=getchar();
20     return x*f;
21 }
22 
23 struct Node {
24     int pos,id,l,r;
25     bool operator < (const Node& rhs) const
26     {
27         return pos<rhs.pos||(pos==rhs.pos&&r<rhs.r);
28     }
29 } q[N];
30 
31 int n,m;
32 int C[N],a[N],hash[N],tot;
33 ll ans[N];
34 
35 void add(int x,int v)
36 {
37     for(;x<=tot;x+=x&-x) C[x]+=v;
38 }
39 ll query(int x)
40 {
41     ll sum=0;
42     for(;x;x-=x&-x) sum+=(ll)C[x];
43     return sum;
44 }
45 
46 int main()
47 {
48     n=read();
49     FOR(i,1,n) a[i]=read(),hash[++tot]=a[i];
50     sort(hash+1,hash+n+1);
51     tot=unique(hash+1,hash+n+1)-hash-1;
52     FOR(i,1,n) a[i]=lower_bound(hash+1,hash+n+1,a[i])-hash;
53     
54     m=read();
55     int B=sqrt(n);
56     FOR(i,1,m) 
57     {
58         q[i].l=read(),
59         q[i].r=read();
60         q[i].id=i;
61         q[i].pos=(q[i].l-1)/B+1;
62     }
63     sort(q+1,q+m+1);
64     
65     ll now=0; 
66     int l=1,r=0;
67     FOR(i,1,m)
68     {
69         while(l<q[i].l)
70             now-=query(a[l]-1),add(a[l],-1),l++;
71         while(l>q[i].l)
72             l--,now+=query(a[l]-1),add(a[l],1);
73         while(r>q[i].r)
74             now-=r-l+1-query(a[r]),add(a[r],-1),r--;
75         while(r<q[i].r)
76             r++,now+=r-l-query(a[r]),add(a[r],1);
77         ans[q[i].id]=now;
78     }
79     
80     FOR(i,1,m) 
81         printf("%lld\n",ans[i]);
82     return 0;
83 }