BZOJ3289——Mato的文件管理

1、题意:排序交换的次数就是逆序对的个数,所以就是求区间逆序对

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

#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;
}
时间: 2024-08-04 03:06:19

BZOJ3289——Mato的文件管理的相关文章

数据离散化 ( 以及 stl 中的 unique( ) 的用法 )+ bzoj3289:Mato的文件管理

http://blog.csdn.net/gokou_ruri/article/details/7723378 ↑惯例Mark大神的博客 bzoj3289:Mato的文件管理 线段树求逆序对+莫队,但是数据量50000却没有给出范围,既然求逆序对,那么我们关注的只是数据之间的相对大小,此时我们可以把这50000个数据进行简化...嗯看大神的博客就明白了不需要多解释什么了..   下面是博客中未授权截取的大神的代码板子....不过都是自己看应该也没什么吧..... sort(sub_a,sub_a

[bzoj3289]Mato的文件管理_莫队_树状数组

Mato的文件管理 bzoj-3289 题目大意:给定一个n个数的序列.m次询问:一段区间中的逆序对个数. 注释:$1\le n\,mle 5\cdot 10^4$. 想法: 开始想这个题的大佬们,给您点儿提示吧:$O(nlogn\sqrt(n))$可过哦! 所以这个题就是莫队的裸题了. 我们的莫队上的区间在动的时候随时更新树状数组上的信息即可.. 然后碰见了一整块区间,我们就直接求逆序对即可, 最后,附上丑陋的代码... ... #include <iostream> #include &l

BZOJ3289 Mato的文件管理

好烦的题,做了我2h,看来蒟蒻就是弱啊... 感觉就是莫队算法来着,然后就走上了乱搞的不归路... 莫队算法详情请上百度搜索,谢谢!>.< 这道题要求逆序对,所以可以用树状数组动态维护.每次转移复杂度就是树状数组点修改的复杂度,但是转移的时候好烦...(一定是我太弱了) 再加上分块,总复杂度为O(n * sqrt(n) * log(n)),刚刚好卡过去... 1 /************************************************************** 2

【莫队算法】bzoj3289 Mato的文件管理

莫队算法,离线回答询问,按一定大小(sqrt(n*log(n))左右)将答案分块,按 ①左端点所在块②右端点 双关键字排序. 然后暴力转移. 转移的时候用树状数组. O(n*sqrt(n)*log(n)). 注意:①在一列数的后面添加一个数,逆序对数会增加 数列中比它大的数的个数. ②在一列数的后面删除一个数,逆序对数会减少 数列中比它大的数的个数. ③在一列数的前面添加一个数,逆序对数会增加 数列中比它小的数的个数. ④在一列数的前面删除一个数,逆序对数会减少 数列中比它小的数的个数. 1 #

【BZOJ3289】Mato的文件管理 莫队算法+树状数组

[BZOJ3289]Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序.排序程序可以在1单位时间内交换2个相邻的文件(因为加密

【bzoj3289】Mato的文件管理

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB Submit: 1056  Solved: 464 [Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.M

BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mat

BZOJ 3289 Mato的文件管理(莫队+离散化求逆序数)

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB Submit: 2171  Solved: 891 [Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.M

bzoj 3289: Mato的文件管理 莫队+树状数组

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先