码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3289——Mato的文件管理

时间:2016-08-22 15:02:10      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

1、题意:排序交换的次数就是逆序对的个数,所以就是求区间逆序对
2、分析:本蒟蒻太垃圾,不会在线做法,直接离线了,思考一下逆序对的求法,跑一边树状数组就好,那么我们使用莫队算法,每次转移的时候就按照这个点对答案的贡献,然后把贡献减掉就行了,时间复杂度O(nnlogn)

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 100010

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < ‘0‘ || ch > ‘9‘){
        if(ch == ‘-‘) f = -1;
        ch = getchar();
    }
    while(‘0‘ <= ch && ch <= ‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
    return x * f;
}

int a[M], b[M], block[M], block_size;

struct Node{
    int l, r, id;

    inline bool operator < (const Node& rhs) const{
        return block[l] < block[rhs.l] || block[l] == block[rhs.l] && block[r] < block[rhs.r] || block[l] == block[rhs.l] && block[r] == block[rhs.r] && l < rhs.l;
    }
} que[M];

int C[M], tot, res[M];

inline void add(int x, int y){
    for(; x <= tot; x += x & -x) C[x] += y;
}

inline int query(int x){
    int ret = 0;
    for(; x > 0; x -= (x & -x)) ret += C[x];
    return ret;
}

int main(){
    //freopen("0input.in", "r", stdin);

    int n = read();
    for(int i = 1; i <= n; i ++) a[i] = b[i] = read();
    sort(b + 1, b + n + 1);
    int L = unique(b + 1, b + n + 1) - b - 1; tot = L;
    for(int i = 1; i <= n; i ++) a[i] = lower_bound(b + 1, b + L + 1, a[i]) - b;
    block_size = sqrt(n);
    for(int i = 1; i <= n; i ++) block[i] = i / block_size + 1;

    int q = read();
    for(int i = 1; i <= q; i ++) que[i].l = read(), que[i].r = read(), que[i].id = i;
    sort(que + 1, que + q + 1); 

    int l = que[1].l, r = que[1].l - 1, ans = 0;
    for(int i = 1; i <= q; i ++){
        while(l < que[i].l){
            add(a[l], -1); ans -= query(a[l] - 1); l ++;
        }
        while(l > que[i].l){
            l --; add(a[l], 1); ans += query(a[l] - 1);
        }
        while(r < que[i].r){
            r ++; add(a[r], 1); ans += r - l + 1 - query(a[r]);
        }
        while(r > que[i].r){
            add(a[r], -1); ans -= r - l - query(a[r]); r --;
        }
        res[que[i].id] = ans;
    }
    for(int i = 1; i <= q; i ++) printf("%d\n", res[i]);
    return 0;
}

BZOJ3289——Mato的文件管理

标签:

原文地址:http://blog.csdn.net/qzh_1430586275/article/details/52276233

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!