zoukankan      html  css  js  c++  java
  • POJ 2299

    POJ 2299 Ultra-QuickSort

    (开头愤怒一句:你妹的下次记得估值范围啊,int64啊!!!)

    题目大意:给出一个序列,问用冒泡排序要交换多少次才能使之变成升序?

    解法:首先分析题目性质,将之转化为求一个数左侧有多少个数小于它,亦转化为一个逆序对的问题。

    因为本题n最大去到50w,所以n^2是万万不能的,所以这里用到一个树状数组求逆序对的问题(也可以用归并排序的做法做)。

    而这里有一个重点:离散化,注意将值一样大的数视为一样大。然后快排,同时记录他的初始位置,然后用数据a(下标同初始位置)记录大小。

    树状数组做法:从最后一个开始,up(a[i], 1);然后ans := ans + getsum(a[i]-1){sum(1, a[i]-1)}因为是从后往前推,所以我只要知道右侧有多少个小于a[i]的数已出现便可直接找到。

    {a[i]表示有多少个是小于I 的,跟线段覆盖有点像?}

    View Code
     1 const
    2 maxn=500000;
    3 var
    4 ans, n: longint;
    5 tree, a, d, p: array[1..maxn+10]of longint;
    6 procedure qsort(b, e: longint);
    7 var
    8 i, j, k, x: longint;
    9 begin
    10 i := b;
    11 j := e;
    12 x := d[(i+j)shr 1];
    13 repeat
    14 while d[i]<x do inc(i);
    15 while d[j]>x do dec(j);
    16 if i<=j then
    17 begin
    18 k := p[i];
    19 p[i] := p[j];
    20 p[j] := k;
    21 k := d[i];
    22 d[i] := d[j];
    23 d[j] := k;
    24 inc(i);
    25 dec(j);
    26 end;
    27 until i>j;
    28 if j>b then qsort(b, j);
    29 if i<e then qsort(i, e);
    30 end;
    31
    32 function lowbit(x: longint): longint;
    33 begin
    34 exit(x and (-x));
    35 end;
    36
    37 procedure up(x, s: longint);
    38 begin
    39 while x<=n do
    40 begin
    41 tree[x] := tree[x] + s;
    42 x := x + lowbit(x);
    43 end;
    44 end;
    45
    46 function getsum(x: longint): longint;
    47 begin
    48 getsum := 0;
    49 while x>=1 do
    50 begin
    51 getsum := getsum + tree[x];
    52 x := x - lowbit(x);
    53 end;
    54 end;
    55
    56 procedure main;
    57 var
    58 i, now: longint;
    59 begin
    60 readln(n);
    61 while n<>0 do
    62 begin
    63 for i := 1 to n do
    64 begin
    65 readln(d[i]);
    66 p[i] := i;
    67 end;
    68 qsort(1, n);
    69 for i := 1 to n do
    70 a[p[i]] := i;
    71 fillchar(tree, sizeof(tree), 0);
    72 ans := 0;
    73 now := 0;
    74 for i := 1 to n do
    75 begin
    76 if (i=1)or(d[i]<>d[i-1]) then inc(now);
    77 a[p[i]] := now;
    78 end;
    79 for i := n downto 1 do
    80 begin
    81 up(a[i], 1);
    82 ans := ans + getsum(a[i]-1);
    83 end;
    84 writeln(ans);
    85 readln(n);
    86
    87 end;
    88 end;
    89
    90 begin
    91 assign(input,'test.in'); reset(input);
    92 assign(output,'test.out'); rewrite(output);
    93
    94 main;
    95
    96 close(input); close(output);
    97 end.



  • 相关阅读:
    不允许修改SQLserver2008r2表中字段的属性问题
    SQL学习笔记 SQL ORDER BY 关键字
    超爱http://www.runoob.com/菜鸟编程
    sqlserver数据类型
    SQL重要命令
    Task--计算器
    改变文本框内容
    Android Studio
    eclipse导入Android项目出现红色感叹号----Solved
    2017-09-09
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435130.html
Copyright © 2011-2022 走看看