[BZOJ3289]Mato的文件管理

思路:

莫队。首先将数据离散化,然后一边莫队一边树状数组求逆序对。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<algorithm>
 6 inline int getint() {
 7     char ch;
 8     while(!isdigit(ch=getchar()));
 9     int x=ch^'0';
10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
11     return x;
12 }
13 struct num {
14     int v,id,rank;
15     bool operator < (const num &x) const {
16         return v<x.v;
17     }
18 };
19 bool cmp(num a,num b) {
20     return a.id<b.id;
21 }
22 int n,r=0;
23 const int N=50001;
24 class FenwickTree {
25     private:
26         int val[N];
27         int lowbit(const int x) {
28             return x&-x;
29         }
30     public:
31         FenwickTree() {
32             memset(val,0,sizeof val);
33         }
34         void modify(int p,const int x) {
35             while(p<=r) {
36                 val[p]+=x;
37                 p+=lowbit(p);
38             }
39         }
40         int query(int p) {
41             int ans=0;
42             while(p) {
43                 ans+=val[p];
44                 p-=lowbit(p);
45             }
46             return ans;
47         }
48 };
49 int base;
50 struct Que {
51     int l,r,id;
52     bool operator < (const Que &x) const {
53         return ((l-1)/base<(x.l-1)/base)?true:(((l-1)/base==(x.l-1)/base)?(r<x.r):false);
54     }
55 };
56 FenwickTree t;
57 int main() {
58     n=getint();
59     num a[n+1];
60     a[0]=(num){0,0,0};
61     for(int i=1;i<=n;i++) a[i]=(num){getint(),i,0};
62     std::sort(&a[1],&a[n+1]);
63     for(int i=1;i<=n;i++) a[i].rank=(a[i].v==a[i-1].v)?r:++r;
64     std::sort(&a[1],&a[n+1],cmp);
65     base=(int)sqrt(n);
66     int m=getint();
67     Que q[m];
68     for(int i=0;i<m;i++) {
69         q[i].l=getint(),q[i].r=getint();
70         q[i].id=i;
71     }
72     std::sort(&q[0],&q[m]);
73     int ans[m];
74     for(int i=0,l=1,r=0,Ans=0;i<m;i++) {
75         while(l<q[i].l) t.modify(a[l].rank,-1),Ans-=t.query(a[l].rank-1),l++;
76         while(r>q[i].r) t.modify(a[r].rank,-1),Ans-=r-l-t.query(a[r].rank),r--;
77         while(l>q[i].l) l--,t.modify(a[l].rank,1),Ans+=t.query(a[l].rank-1);
78         while(r<q[i].r) r++,t.modify(a[r].rank,1),Ans+=r-l+1-t.query(a[r].rank);
79         ans[q[i].id]=Ans;
80     }
81     for(int i=0;i<m;i++) printf("%d\n",ans[i]);
82     return 0;
83 }

 

posted @ 2017-07-12 14:57  skylee03  阅读(140)  评论(0编辑  收藏  举报