zoukankan      html  css  js  c++  java
  • BZOJ2141/BSOJ3904 排队

    BZOJ2141/BSOJ3904 排队

    题意:给定一个序列,求逆序对个数,每次可以交换两个数。((nleq 2*10^4) ,(mleq 2*10^3)

    直接先处理第一次的答案,然后再考虑交换对答案的贡献。

    因为 (n,m)都很小,所以可以直接暴力查询每次改变的量即可。

    时间复杂度 (O(nlogn+nm))

    yhx的做法:

    然后就行了,因为我是口胡,所以再贴一下他的代码。

    #include <bits/stdc++.h>
    #define sgn(i, j) ((a[i] > a[j]) - (a[i] < a[j])) // sgn(c[i] - c[j])
    #define N 20034
    using namespace std;
    
    int n, q, i;
    int l, r, ans = 0;
    int a[N], buf[N], tmp[N];
    
    int MergeSort(int L, int R){ // mergesort[L, R)
        if(L + 1 == R) return L;
        int M = L + R >> 1;
        MergeSort(L, M);
        MergeSort(M, R);
        int i, j, k = L;
        memcpy(tmp + L, buf + L, M - L << 2);
        for(i = L, j = M; i < M || j < R; )
            if(j >= R || (i < M && tmp[i] <= buf[j]))
                buf[k++] = tmp[i++];
            else{
                buf[k++] = buf[j++];
                ans += M - i;
            }
        return L;
    }
    
    int main(){
        scanf("%d", &n);
        for(i = 1; i <= n; i++)
            scanf("%d", a + i);
        memcpy(buf + 1, a + 1, n << 2);
        MergeSort(1, n + 1);
        printf("%d
    ", ans);
        for(scanf("%d", &q); q; q--){
            scanf("%d%d", &l, &r);
            if(l > r) swap(l, r);
            if(a[l] == a[r]){
                printf("%d
    ", ans);
                continue;
            }
            for(i = l; i < r; i++)
                ans += sgn(i, l) + sgn(r, i);
            swap(a[l], a[r]);
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    

    yhx's solution

  • 相关阅读:
    图片放大功能
    谈论算法
    socket基础
    js实现快速排序
    mysql死锁问题分析(转)
    MVCC 专题
    ActiveMQ持久化方式(转)
    消息队列中点对点与发布订阅区别(good)
    tomcat下部署activemq(转)
    Android文件下载(实现断点续传)
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14653163.html
Copyright © 2011-2022 走看看