• 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

  • 相关阅读:
    NPOI操作Excel
    父窗口调用iframe子窗口方法
    js 全选全不选
    常用的几种 SQLServer 分页查询方式实现
    通用简单的 分页 SQL
    C#导出
    delphi xe firemonkey 调用VLC播放器播放视频
    Android版本和API Level对应关系
    Android开发之视频录制1
    Android上实现视频录制
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14653163.html
Copyright © 2020-2023  润新知