归并算法实现求解逆序对【模板】

已用此模板过掉了好几题。

#include<stdio.h>
#define LL long long //以后可以考虑这样写 简洁

int n,i,a[500010], b[500010];
//需要开辟两个数组

LL count(int l,int r)//统计[l ,r]的逆序对数
{
    LL s=0;//初始化
    int mid=(l+r)/2, i=l, j=mid+1, k=l;
    //printf("%d \n", mid );

    if (l<mid) s+=count(l,mid);//计算累加左区间的逆序对
    if (mid+1<r) s+=count(mid+1,r);//计算累加右区间的逆序对

    while( i<=mid || j<=r )
    {
        while ( i<=mid && (j>r || a[i]<=a[j]) ){
            //printf("%d < %d", a[i], a[j] ); //左边理应小于右边(左边等级低 右边等级高)
            b[k++]=a[i++];
        }
        while ( j<=r && (i>mid || a[j]<a[i]) )
        {                        //右边的大于左边的进行计数
           // printf(" %d-<-%d ", a[j], a[i] );
            b[k++]=a[j++];
            s+=mid-i+1;
        }
    }
    for(i=l;i<=r;i++)
        a[i]=b[i];
    return s;
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for (i=0; i<n; i++)
            scanf("%d", &a[i]);
        printf("%lld\n", count(0,n-1));
    }
    return 0;
}
时间: 2024-10-24 23:22:24

归并算法实现求解逆序对【模板】的相关文章

poj2299--归并排序求解逆序对

1.题目链接 http://acm.hrbust.edu.cn/vj/index.php?c=problem-problem&id=166400 2.代码: //归并排序求解逆序对 #include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> #include<stack> #include<queue> #include<string

归并排序求逆序对模板(未完待续)

归并排序求逆序对题目(持续更新) \(1.\) \(Ultra\) \(Quicksort\) (需要该篇博文的阅读密码) 归并排序求逆序对 细节:传参三个,左.中.右三端点,每次运算注意中端点总取左右端点和的一半:返回条件为左右端点相等,此时无需排序. \(View\) \(Code\) void msort(int l,int mid,int r) { if(l==r) return; msort(l,(l+mid)>>1,mid); msort(mid+1,(r+mid+1)>&g

逆序对模板(树状数组)

//P1908 逆序对 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mxn=5e5+5; int a[mxn],c[mxn],b[mxn],f[mxn]; int n; inline int lowbit(int x){ return x&-x; } inline ll get(int x){ ll sum=0; for(;x;x-=lowbit(x)){ sum+=c[x];

娘的,自己的求逆序对模板又不好使了。。。。。。。。

#include<stdio.h> long long cnt; long long a[500001],t[500001]; void merge(long long *a,long long *t,int l,int m,int r) { int p = l; int q = m+1; int k = p; while(p <= m||q <= r) { if(q > r||(p <= m&&a[p] <= a[q])) t[k++] = a[

逆序对模板

#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int N=550005; int n,a[N],c[N]; long long ans; void ready() { cin>>n; for(int i

树状树组离散化求逆序对模板

#include <iostream> #include <cstring> #include <stack> #include <cstdio> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <set> #include <map> using namespace st

二分&#183;归并排序之逆序对 算法讲解和题目

题目: #1141 : 二分·归并排序之逆序对 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回.上上回以及上上上回里我们知道Nettle在玩<艦これ>.经过了一番苦战之后,Nettle又获得了的很多很多的船.这一天Nettle在检查自己的舰队列表:我们可以看到,船默认排序是以等级为参数.但实际上一个船的火力值和等级的关系并不大,所以会存在A船比B船等级高,但是A船火力却低于B船这样的情况.比如上图中77级的飞龙改二火力就小于55级的夕立改二.现在Nett

逆序对的两种求法(复习)

逆序对 对于一个数列\(a_1...a_n\),定义一有序对\((i,j)\)当且仅当\(i<j\)且\(a_i>a_j\)为逆序对.接着我们来考虑怎么求 *1. 归并排序 回顾归并排序的过程,将当且的数列\([l,r]\)分成两个长度相等的部分\([l,mid]\)和\([mid+1,r]\),分治下去排序,每次合并的代价是区间的长度,所以得到时间复杂度为: \[ T(n)=2T(\frac{n}{2})+O(n) \] 根据\(master\)定理可知时间复杂度为\(\Theta(nlog

【CQOI2011】动态逆序对 BZOJ3295

Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数.以下n行每行包含一个1到n之间的正整数,即初始排列.以下m行每行一个正整数,依次为每次删除的元素. Output 输出包含m行,依次为删除每个元素之前,逆序对的个数. Sample Input 5 4 1 5 3