zoukankan      html  css  js  c++  java
  • 求逆序数模板(树状数组+离散化 || 归并排序法)

    一篇不错的解说:http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html


    代码例如以下:(树状数组+离散化)

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=500017;
    int n;
    int aa[maxn];   //离散化后的数组
    int c[maxn];    //树状数组
     
    struct Node
    {
       int v;
       int order;
    }in[maxn];
     
    int Lowbit(int x) //2^k
    {
        return x&(-x);
    }
    
    void update(int i, int x)//i点增量为x
    {
    	while(i <= n)
    	{
    		c[i] += x;
    		i += Lowbit(i);
    	}
    }
    int sum(int x)//区间求和 [1,x]
    {
    	int sum=0;
    	while(x>0)
    	{
    		sum+=c[x];
    		x-=Lowbit(x);
    	}
    	return sum;
    }
    
    bool cmp(Node a ,Node b)
    {
        return a.v < b.v;
    }
    
    int main()
    {
        int i,j;
        while(scanf("%d",&n) && n)
        {
            //离散化
            for(i = 1; i <= n; i++)
            {
                scanf("%d",&in[i].v);
                in[i].order=i;
            }
            sort(in+1,in+n+1,cmp);
            for(i = 1; i <= n; i++) 
    			aa[in[i].order] = i;
            //树状数组求逆序
            memset(c,0,sizeof(c));
            __int64 ans=0;
            for(i = 1; i <= n; i++)
            {
                update(aa[i],1);
                ans += i-sum(aa[i]);//逆序数个数
            }
    		printf("%I64d
    ",ans);
        }
        return 0;
    }


    代码例如以下:(归并排序法)

    int is1[112345],is2[112345];// is1为原数组,is2为暂时数组,n为个人定义的长度
    
    __int64 merge(int low,int mid,int high)
    {
    	int i=low,j=mid+1,k=low;
    	__int64 count=0;
    	while(i<=mid&&j<=high)
    		if(is1[i]<=is1[j])// 此处为稳定排序的关键。不能用小于
    			is2[k++]=is1[i++];
    		else
    		{
    			is2[k++]=is1[j++];
    			count+=j-k;// 每当后段的数组元素提前时。记录提前的距离
    		}
    		while(i<=mid)
    			is2[k++]=is1[i++];
    		while(j<=high)
    			is2[k++]=is1[j++];
    		for(i=low;i<=high;i++)// 写回原数组
    			is1[i]=is2[i];
    		return count;
    }
    __int64 mergeSort(int a,int b)// 下标,比如数组int is[5],所有排序的调用为mergeSort(0,4)
    {
    	if(a<b)
    	{
    		int mid=(a+b)/2;
    		__int64 count=0;
    		count+=mergeSort(a,mid);
    		count+=mergeSort(mid+1,b);
    		count+=merge(a,mid,b);
    		return count;
    	}
    	return 0;
    }


  • 相关阅读:
    【CTF杂项】常见文件文件头文件尾格式总结及各类文件头
    修复XSS跨站漏洞
    XSS高级利用
    i春秋-百度杯十月场-EXEC
    i春秋-百度杯十月场-vld
    i春秋-百度杯十月场-fuzzing
    阿里云轻量应用服务器debian8.9用apache多端口搭建多站点
    Hdu 1873 看病要排队
    Hdu 1870 愚人节的礼物
    Hdu 1864 最大报销额
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5269321.html
Copyright © 2011-2022 走看看