首页 > 代码库 > BZOJ 3289:Mato的文件管理(莫队算法+树状数组)

BZOJ 3289:Mato的文件管理(莫队算法+树状数组)

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

题意:……

思路:求交换次数即求逆序对数。确定了这个之后,先离散化数组。然后在后面插入元素的话,就是在区间里面找比它大的元素数量,在前面插入元素的话,就是在区间里面找比它小的元素数量。删除操作类似。因为排序是从小到大排序,所以要找比它大的数量就是区间长度减去小于等于该元素的数量,所以是(R - L + 1 - sum(a[i])),要找比它小的数量就是(sum(a[i] - 1))。然后用莫队算法处理区间询问就好了。

 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 #define N 50010 7 struct node { 8     int l, r, id, ans; 9 } p[N];10 int bit[N], a[N], b[N], num[N], ans, kuai, n;11 12 bool cmp(const node &a, const node &b) {13     if(a.l / kuai == b.l / kuai) return a.r < b.r;14     return a.l / kuai < b.l / kuai;15 }16 bool cmpid(const node &a, const node &b) { return a.id < b.id; }17 int lowbit(int x) { return x & (-x); }18 void add(int x, int w) { for( ; x <= n; x += lowbit(x)) bit[x] += w; }19 int sum(int x) { int ans = 0; for( ; x ; x -= lowbit(x)) ans += bit[x]; return ans; }20 21 int main() {22     while(~scanf("%d", &n)) {23         for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];24         int q; scanf("%d", &q);25         for(int i = 1; i <= q; i++) scanf("%d%d", &p[i].l, &p[i].r), p[i].id = i;26 27         memset(bit, 0, sizeof(bit));28         ans = 0; kuai = sqrt(n);29         sort(b + 1, b + 1 + n);30         int cnt = unique(b + 1, b + 1 + n) - b - 1;31         for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + cnt, a[i]) - b;32 33         sort(p + 1, p + 1 + q, cmp);34         for(int L = 1, R = 0, i = 1; i <= q; i++) {35             int l = p[i].l, r = p[i].r;36             for( ; L < l; L++) { ans -= sum(a[L] - 1); add(a[L], -1); }37             for( ; L > l; L--) { ans += sum(a[L-1] - 1); add(a[L-1], 1); }38             for( ; R < r; R++) { ans += R - L + 1 - sum(a[R+1]); add(a[R+1], 1); }39             for( ; R > r; R--) { ans -= R - L + 1 - sum(a[R]); add(a[R], -1); }40             p[i].ans = ans;41         }42         sort(p + 1, p + 1 + q, cmpid);43         for(int i = 1; i <= q; i++) printf("%d\n", p[i].ans);44     }45     return 0;46 }

 

BZOJ 3289:Mato的文件管理(莫队算法+树状数组)