归并排序求逆序对数

Codevs

/*
作者:thmyl
题目:p1688 求逆序对
*/
#include<iostream>
using namespace std;
long long  n,a[1000000],tot,temp[10000000];
void sor(int l,int r)
{
    if(l==r)return ;
    int mid=(l+r)/2;
    sor(l,mid);
    sor(mid+1,r);
    int i=l,p=l,j=mid+1;
    while(i<=mid&&j<=r)
    {
        if(a[i]>a[j])tot+=mid-i+1,temp[p++]=a[j++];
        else temp[p++]=a[i++];
    }
    while(i<=mid)temp[p++]=a[i++];
    while(j<=r)temp[p++]=a[j++];
    for(int i=l;i<=r;i++)a[i]=temp[i];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
      cin>>a[i];
    sor(1,n);
    cout<<tot;
}
时间: 2024-10-19 15:00:46

归并排序求逆序对数的相关文章

POJ 2299 Ultra-QuickSort(归并排序求逆序对数)

题目地址:POJ 2299 今天下午的多校看来没有白做...实在做不出题闲着无聊看小白鼠学会了个归并排序.哈哈. 归并排序简单地说其实就是先分成一个二叉树直至单个,然后依次从最底层不断进行合并,逆序对数就是在合并的过程中,加入后面的那段中到了比他大的时候,那后面的那些就都是比他大的,都是逆序对数,所以直接加上即可.网上资料很多,就不细说了..用了分治的思想. 自己根据理解写的代码,考虑的太不全面了..又调了好长时间... 代码如下: #include <algorithm> #include

hdu 4911 Inversion(归并排序求逆序对数)

Inversion                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two 

hdu 4911 Inversion(归并排序求逆序对数)2014多校训练第5场

Inversion                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two 

Time Limit Exceeded 求逆序对数。

/** 题目:Time Limit Exceeded 链接:https://oj.ejq.me/problem/28 题意:求逆序对数. 思路:树状数组求逆序对数.维护前面有多少个<=当前数的数的个数. */ #include<bits/stdc++.h> typedef long long ll; using namespace std; const int maxn = 1e6+10; const int mod = 1e9+7; ll c[maxn]; int flag[maxn]

POJ 2299 Ultra-QuickSort (树状数组or 归并排序分治求逆序对数)

题目大意就是说帮你给一些(n个)乱序的数,让你求冒泡排序需要交换数的次数(n<=500000) 显然不能直接模拟冒泡排序,其实交换的次数就是序列的逆序对数. 由于数据范围是 0 ≤ a[i] ≤ 999,999,999所以先要离散化,然后用合适的数据结果求出逆序 可以用线段树一步一步添加a[i],每添加前查询前面添加比它的大的有多少个就可以了. 也可用树状数组,由于树状数组求的是(1...x)的数量和所以每次添加前查询i-sum(a[i])即可 树状数组: //5620K 688MS #incl

zoj 3157 Weapon 线段树求逆序对数

题目链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemId=3128 题意:平面上有n条直线,给出l, r,求出这些直线的交点横坐标在(l, r)范围内的个数. 思路: 首先求出每条直线与直线x = l和直线x = r的交点,如下图. 因为题目要求区间(l, r)是开区间,所以为了避免交点的横坐标刚好是l或者r的情况,可以先把l加上一个很小的值,r减去一个很小的值,如图中的灰线. 然后求出各条直线与两条灰线的交点,首先按与l的交点的

POJ-2299 Ultra-QuickSort(用树状数组求逆序对数)

题目链接 ac代码 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #include<cassert> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include&

POJ 2299 Ultra-QuickSort (求序列的逆序对数)

题意:废话了一大堆就是要你去求一个序列冒泡排序所需的交换的次数. 思路:实际上是要你去求一个序列的逆序队数 看案例: 9 1 0 5 4 9后面比它小的的数有4个 1后面有1个 0后面没有 5后面1个 4后面没有 所以结果为4+1+0+1+0=6 所以逆序对的定义如果不清楚可以自己总结了 这道题说白了就是要你用归并排序求逆序对数. 下面是搜到某牛给的逆序对数的方法: 假设回溯到某一步,后面的两部分已经排好序(就是说当前需要归并的两个部分都是分别有序的),假设这两个序列为 序列a1:2 3 5 9

归并排序求逆序对 //(洛谷)U4566 赛车比赛

https://www.luogu.org/problem/show?pid=U4566 显然的逆序对,以前只是嘴巴ac,这次终于打了出来. 逆序对其实就是冒泡排序的排序次数....但是一般的排序时间复杂度为O(n^2),于是都会想到归并排序... 一.二路归并 已知两个有序数组,将其归并为一个有序数组 很显然,将首元素比较,小的扔进目的数组,最后把剩下的扔进去.. 1 int a[n],b[m],tmp[n+m]; 2 int i=1,j=1,k=1; 3 while(i<=n&&