zoukankan      html  css  js  c++  java
  • SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180

    解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组。因为这题中的数列有重复的而且范围特别大,所以要进行离散化,离散化的方法是,

    首先按照输入的数字排个序,然后把整个数列扫一遍,得出每个数字离散化的结果,然后再按照输入的顺序把顺序调整回来就OK 了。线段树部分就不说了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef __int64 INT;
     7 const int maxn = 65537+5;
     8 
     9 struct node
    10 {
    11     int data,cixu,dd;
    12 }que[maxn];
    13 
    14 struct Node
    15 {
    16     INT data;
    17     int l,r;
    18 }tree[2*maxn];
    19 
    20 bool cmp1(node a,node b)
    21 {
    22     return a.data <= b.data;
    23 }
    24 bool cmp2(node a,node b)
    25 {
    26     return a.cixu < b.cixu;
    27 }
    28 void maketree(int p)
    29 {
    30     if(tree[p].l == tree[p].r)
    31     return ;
    32     int mid = (tree[p].l + tree[p].r) / 2;
    33     tree[2*p].data = 0;
    34     tree[2*p].l = tree[p].l;
    35     tree[2*p].r = mid;
    36     maketree(2*p);
    37     tree[2*p+1].data = 0;
    38     tree[2*p+1].l = mid + 1;
    39     tree[2*p+1].r = tree[p].r;
    40     maketree(2*p+1);
    41 }
    42 INT find(int p,int l,int r)
    43 {
    44     if(l >  r)
    45     return 0;
    46     if(tree[p].l == l && tree[p].r == r)
    47     return tree[p].data;
    48     int mid = (tree[p].l + tree[p].r) / 2;
    49     if(r <= mid)
    50     return find(2*p,l,r);
    51     else if(l <= mid && r > mid)
    52     return find(2*p,l,mid) + find(2*p+1,mid + 1,r);
    53     else return find(2*p+1,l,r);
    54 }
    55 void push(int p,int d)
    56 {
    57     tree[p].data++;
    58     if(tree[p].l == tree[p].r)
    59     return ;
    60     int mid = (tree[p].l + tree[p].r) / 2;
    61     if(d <= mid)
    62     push(2*p,d);
    63     else push(2*p+1,d);
    64 }
    65 int main()
    66 {
    67     int n;
    68     scanf("%d",&n);
    69     for(int i = 1;i <= n;++i)
    70     {
    71         scanf("%d",&que[i].data);
    72         que[i].cixu = i;
    73     }
    74     sort(que+1,que+n+1,cmp1);
    75     int f = -1;
    76     que[0].data = 0x7fffffff;   //只要一个跟所有输入的数都不同的就行了
    77     for(int i = 1;i <= n;++i)
    78     {
    79         if(que[i].data != que[i-1].data)
    80         f++;
    81         que[i].dd = f;
    82     }
    83     tree[1].data = 0;
    84     tree[1].l = 0;
    85     tree[1].r = f;
    86     maketree(1);
    87     sort(que+1,que+n+1,cmp2);
    88     INT tot = 0;
    89     for(int i = 1;i <= n;++i)
    90     {
    91         tot += find(1,que[i].dd + 1,f);
    92         push(1,que[i].dd);
    93     }
    94     printf("%I64d
    ",tot);
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3850169.html
Copyright © 2011-2022 走看看