zoukankan      html  css  js  c++  java
  • poj 2299 Ultra-QuickSort(归并排序 树状数组)

    题意 :交换相邻的两个数来排序 最少交换几次

    思路:

    题意可以转化成求 数列中存在几个逆序数

    可以看作冒泡排序 但是复杂度过高 可以用归并排序 和离散化的树状数组来完成

    (注意 n<=5000000 所以ans 要用 长整型 )

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[5000000+100];
    int t[5000000+100];
    __int64 ans;
    int l,r;
    void merge(int x,int y)
    {
        if(y-x>1)
        {
            int m=x+(y-x)/2;
            int p=x,q=m,i=x;
            merge(x,m);
            merge(m,y);
            while(p<m||q<y)
            {
                if(q>=y||(p<m&&a[p]<=a[q])) t[i++]=a[p++];
                else
                    {
                        if(p<m)
                        {
                            //printf("%d %d...
    ",a[p],a[q]);
                            ans+=(m-p);
                        }
                        t[i++]=a[q++];
                    }
            }
            for(i=x;i<y;i++) a[i]=t[i];
           // printf("%d %d %d
    ",x,m,y);  for(i=0;i<r;i++) printf("%d ",a[i]);  printf("
    
    
    ");
        }
    }
    int main()
    {
        int n;
        int i,j,k;
        while(scanf("%d",&n),n)
        {
            ans=0;
            for(i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            //l=0;r=n;
            merge(0,n);
            printf("%I64d
    ",ans);
        }
        return 0;
    }

    树状数组 

    #include<cstdio>
    #include<cmath>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,c[500000+10],reflect[500000+10];
    __int64 ans;
    
    struct node
    {
        int val,pos;
    };
    node a[500000+10];
    
    int cmp(node x,node y)
    {
        return x.val<y.val;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    int sum(int x)
    {
        int ret=0;
        while(x>0)
        {
            ret+=c[x];
            x-=lowbit(x);
        }
        return ret;
    }
    
    void add(int x)
    {
        while(x<=n)
        {
            c[x]+=1;
            x+=lowbit(x);
        }
    }
    int main()
    {
        while(scanf("%d",&n),n)
        {
            ans=0;
            memset(c,0,sizeof(c));
            int i,j;
            for(i=1;i<=n;i++){ scanf("%d",&a[i].val); a[i].pos=i;}
            sort(a+1,a+n+1,cmp);
            for(i=1;i<=n;i++) {reflect[a[i].pos]=i;}
    
            for(i=1;i<=n;i++)
            {
                add(reflect[i]);
                ans+=i-sum(reflect[i]);
                printf("%I64d
    ",ans);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    面试知识点2
    面试知识点3
    面试知识记录
    JQuery手写一个简单的轮播图
    推荐一款好用的日历插件
    JQuery获取复选框的值
    JQuery手写一个简单的分页
    JQuery给一个元素绑定两次点击事件(第二次点击事件)
    懒加载预加载(图片)
    JQuery Ajax 使用FormData上传文件对象
  • 原文地址:https://www.cnblogs.com/sola1994/p/4260864.html
Copyright © 2011-2022 走看看