zoukankan      html  css  js  c++  java
  • poj 2299 逆序数 树状数组 归并

    方法一:树状数组

    1.树状数组讲解http://www.cnblogs.com/inpeace7/archive/2012/04/11/2441352.html

    2.离散化

     输入a[i]

          i   1   2   3   4   5     6       7

         a[i] 50 60 80 90  20  100     50

         p[i] 2  3    4   5    1     6        2

    把a[i]变为p[i]即为离散化

    方法:定义结构体,存储a[i]和i,按照a[i]排序,

    p[node[1].data]=1;

    int cnt=1;

    for(i=1;i<n;i++)

    {

      if(node[i-1].data=node[i].data) p[node[i].in]=cnt;

      else p[node[i].in]=++cnt;

    }

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <stdio.h>
     4 #include <string.h>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 #define lowbit(x) ((x)&(-x))
     9 
    10 const int maxx=500000;
    11 ll tree[maxx+10];
    12 int index[maxx+10];
    13 int n;
    14 struct NODE
    15 {
    16     ll data;
    17     int in;
    18 }node[maxx+10];
    19 
    20 int cmp(NODE a,NODE b)
    21 {
    22     if(a.data!=b.data) return a.data<b.data;
    23     else return a.in<b.in;
    24 }
    25 
    26 void update(int i,int val)
    27 {
    28     while(i<=n)
    29     {
    30         tree[i]+=val;
    31         i+=lowbit(i);
    32     }
    33 }
    34 
    35 ll getsum(int i)
    36 {
    37     ll sum=0;
    38     while(i>0)
    39     {
    40         sum+=tree[i];
    41         i-=lowbit(i);
    42     }
    43 
    44     return sum;
    45 }
    46 
    47 int main()
    48 {
    49     int i,cnt;
    50     ll ans;
    51    // freopen("in.txt","r",stdin);
    52     while(scanf("%d",&n)!=EOF)
    53     {
    54         if(n==0) break;
    55         ans=0;
    56         memset(tree,0,sizeof(tree));
    57         for(i=1;i<=n;i++){scanf("%lld",&node[i].data);node[i].in=i;}
    58         sort(node+1,node+n+1,cmp);
    59         index[node[1].in]=1;
    60         cnt=1;
    61         for(i=2;i<=n;i++)
    62         {
    63             if(node[i].data==node[i-1].data) index[node[i].in]=cnt;
    64             else index[node[i].in]=++cnt;
    65             //cout<<"**"<<index[node[i].in]<<" "<<node[i].data<<endl;
    66         }
    67         for(i=1;i<=n;i++)
    68         {
    69             update(index[i],1);
    70             ans+=(ll)(i-getsum(index[i]));
    71         }
    72         printf("%lld\n",ans);
    73     }
    74 
    75     return 0;
    76 }

    方法二:归并

     1 #include <iostream>
     2 #include <stdio.h>
     3 
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxx= 500000,inf=0x7fffffff;
     7 ll L[maxx/2+10],R[maxx/2+10],a[maxx+10],cnt;
     8 
     9 void mergee(int p,int q,int r)
    10 {
    11     int n1=q-p+1,n2=r-q,i,j,k;
    12     for(i=0;i<n1;i++) L[i]=a[p+i];
    13     for(i=0;i<n2;i++) R[i]=a[q+i+1];
    14     i=0,j=0,L[n1]=inf,R[n2]=inf;
    15     for(k=p;k<=r;k++)
    16     {
    17         if(L[i]<=R[j]){a[k]=L[i];i++;}
    18         else {a[k]=R[j];j++;cnt=cnt+n1-i;}
    19     }
    20 }
    21 
    22 void mergesort(int p,int r)
    23 {
    24     if(p<r)
    25     {
    26         int q=(p+r)/2;
    27         mergesort(p,q);
    28         mergesort(q+1,r);
    29         mergee(p,q,r);
    30     }
    31 }
    32 int main()
    33 {
    34     int n,i;
    35     freopen("in.txt","r",stdin);
    36     while(scanf("%d",&n)!=EOF)
    37     {
    38         if(n==0) break;
    39         cnt=0;
    40         for(i=0;i<n;i++)scanf("%lld",a+i);
    41         mergesort(0,n-1);
    42         printf("%lld\n",cnt);
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    Hive系统函数之collect_list和collect_set
    SpringBoot集成JWT实现token验证
    Hadoop添加LZO压缩支持
    常见函数封装(自用,随时更新)
    vs-code 的常用插件
    在移动端显示控制台信息
    SublimeText 3 常见快捷键
    vue的自定义指令
    修改滚动条样式
    vue、react中循环遍历为什么会有key,key有什么作用?
  • 原文地址:https://www.cnblogs.com/inpeace7/p/2442858.html
Copyright © 2011-2022 走看看