• POJ 2299 离散化线段树


    Ultra-QuickSort
    Time Limit: 7000MS   Memory Limit: 65536K
    Total Submissions: 40827   Accepted: 14752

    Description

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output 
    0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0

    求冒泡排序交换的次数。
    因为这些数可能太大。且差距非常大,所以离散化一下,然后求一下逆序数。边查询边插入边就可以。


    //32684K	1579MS
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define M 500007
    #define ll __int64
    using namespace std;
    int s[M],n;
    struct Tree
    {
        int l,r,mid;
        ll val;
    }tree[M<<1];
    struct sa
    {
        int id;
        ll val;
    }p[M*2];
    int cmp(sa a,sa b)
    {
        return a.val>b.val;
    }
    void build(int left,int right,int i)
    {
        tree[i].l=left;tree[i].r=right;tree[i].mid=(left+right)>>1;tree[i].val=0;
        if(left==right){return;}
        build(left,tree[i].mid,i*2);
        build(tree[i].mid+1,right,i*2+1);
    }
    int query(int x,int i)
    {
        if(tree[i].l==tree[i].r)return tree[i].val;
        if(x<=tree[i].mid)return query(x,i*2)+tree[i].val;
        else return query(x,i*2+1)+tree[i].val;
    }
    void insert(int left,int right,int i)
    {
        if(tree[i].l==left&&tree[i].r==right){tree[i].val++;return;}
        if(right<=tree[i].mid)insert(left,right,2*i);
        else if(left>tree[i].mid)insert(left,right,2*i+1);
        else {insert(left,tree[i].mid,i*2);insert(tree[i].mid+1,right,i*2+1);}
    }
    void discretization()
    {
        int tmp=p[1].val,pos=1;
        for(int i=1;i<=n;i++)
            if(p[i].val!=tmp)p[i].val=++pos,tmp=p[i].val;
            else p[i].val=pos;
        for(int i=1;i<=n;i++)
            s[p[i].id]=p[i].val;
    }
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            ll ans=0;
            build(0,M,1);
            memset(s,0,sizeof(s));
            for(int i=1;i<=n;i++)
            {
                scanf("%I64d",&p[i].val);
                p[i].id=i;
            }
            sort(p+1,p+n+1,cmp);
            discretization();
            for(int i=1;i<=n;i++)
                printf("%d ",s[i]);
            printf("
    ");
            for(int i=1;i<=n;i++)
            {
                    ans+=query(s[i],1);
                    insert(s[i],M,1);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    JSON格式
    多行写入
    文件对象write() and read()
    一个虚拟摄像头Filter(Virtual Cam Capture Filter)
    五十种最好的开源爬虫
    web scraper 里的 Element click 模拟点击「加载更多」
    介绍一款好用又易学的爬虫工具:web scraper
    安装宝塔面板后 ,centos系统 挂载硬盘 或者 数据盘和系统盘合并
    帝国CMS恢复搜索功能 增加搜索数据源设置教程
    安装帝国CMS步骤 和恢复数据
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6908152.html
Copyright © 2020-2023  润新知