• 模板——权值线段树(逆序对)


    Ultra-QuickSort
    Time Limit: 7000MS   Memory Limit: 65536K
    Total Submissions: 62455   Accepted: 23259

    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
    

    Source

     
    大意就是给若干个长度为n的序列求逆序对个数。
    权值线段树维护的是某个值出现的次数,所以一开始是空树(换句话说就不用建树了2333),然后不断按顺序从左到右插入点,很显然每插入一个点就记录比这个点大的个数即为此时的逆序对个数,然后累计即可。
    (其实就是用线段树维护计数数组)
    因为数值可达9亿9千9百9十9万9千9百9十9,但个数最多只有500000,所以先离散后插入。(ans要long long!!!)
     
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,a[500005],tmp[500005],size;
     7 long long ans,cnt[2000005];
     8 void init(int root,int l,int r,int x){
     9     if ((l==r)&&(l==x)) {
    10         cnt[root]++;
    11         return;
    12     }
    13     int mid=(l+r)>>1;
    14     if (x<=mid) init(root<<1,l,mid,x);
    15     else if (x>mid) init(root<<1|1,mid+1,r,x);
    16     cnt[root]=cnt[root<<1]+cnt[root<<1|1];
    17 }
    18 long long sum(int root,int l,int r,int x,int y){
    19     if ((x<=l)&&(y>=r)) return cnt[root];
    20     long long anss=0;
    21     int mid=(l+r)>>1;
    22     if (x<=mid) anss+=sum(root<<1,l,mid,x,y);
    23     if (y>mid) anss+=sum(root<<1|1,mid+1,r,x,y);
    24     return anss;
    25 }
    26 int main(){
    27     scanf("%d",&n);
    28     while (n){
    29         memset(a,0,sizeof(a));
    30         memset(cnt,0,sizeof(cnt));
    31         memset(tmp,0,sizeof(tmp));
    32         size=0;
    33         ans=0;
    34         for (int i=1;i<=n;i++){
    35          scanf("%d",&a[i]);
    36          tmp[i]=a[i];
    37         }
    38         sort(tmp+1,tmp+1+n);
    39         size=unique(tmp+1,tmp+1+n)-(tmp+1);
    40         for (int i=1;i<=n;i++)
    41          a[i]=lower_bound(tmp+1,tmp+1+size,a[i])-(tmp+1)+1;
    42         for (int i=1;i<=n;i++){
    43          init(1,1,n,a[i]);
    44          ans+=sum(1,1,n,a[i]+1,n);
    45         }
    46         printf("%lld
    ",ans);
    47         scanf("%d",&n);
    48     }
    49     return 0;
    50 }
    神奇的代码
     
  • 相关阅读:
    配置对即时负载的优化
    通过重组索引提高性能
    使用索引视图提高性能
    sqlcmd
    (转)使用SQLCMD在SQLServer执行多个脚本
    在SQLServer处理中的一些问题及解决方法 NEWSEQUENTIALID()
    java反射机制与动态代理
    天天用的开发环境,你真的了解吗?
    通过IP获取对应所在地的地址
    unity3d KeyCode各键值说明
  • 原文地址:https://www.cnblogs.com/Lanly/p/7327844.html
Copyright © 2020-2023  润新知