zoukankan      html  css  js  c++  java
  • 多校hdu-5775 Bubble sort(线段树)

    题意根据题目中给的冒泡排序写出每个元素交换过程中该元素位置左右最大差距;

    分析:因为题目中冒泡程序从后向前遍历的,假设第i个元素左边有k个比i小的数,那么i必定会向右移动k位,我们用k1记住i+k,用k2记住i最终移到的位置a[i],用k3记住i的初始位置i,那么左右的最大值和最小值一定在k1,k2,k3中产生,此处不做证明,自己可以仔细想想。

    现在主要问题在于寻找第i位置的左区间有几个比a[i]大的就可以了,解决办法:用线段树的节点储存次在节点左右区间的a[i]的个数,初始化为0,从a[n]到a[1]查询(1,a[i]-1)区间的数的个数,在把a[i]扔到线段树中更新就可以了。

    代码如下:

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <map>
    #include <string.h>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int N=100010;
    int g[4*N];
    void creat(int k,int l,int r)
    {
         if(l==r)
         {
            g[k]=0;
            return ;
         }
         int mid=(l+r)/2;
         creat(k<<1,l,mid);
         creat(k<<1|1,mid+1,r);
         g[k]=0;
    }
    int finds(int k,int l,int r,int L,int R)
    {
         if(l>=L&&r<=R)
         {
             return g[k];
         }
         int mid=(l+r)/2;
         int k1=0,k2=0;
         if(mid>=L)
         {
             k1=finds(k<<1,l,mid,L,R);
         }
         if(mid<R)
         {
             k2=finds(k<<1|1,mid+1,r,L,R);
         }
         return k1+k2;
    }
    void  updata(int k,int l,int r,int x)
    {
         if(l==r&&l==x)
         {
             g[k]=1;
             return ;
         }
         int mid=(l+r)/2;
         if(x<=mid)
         {
             updata(k<<1,l,mid,x);
             g[k]+=1;
         }
         if(x>mid)
         {
            updata(k<<1|1,mid+1,r,x);
            g[k]+=1;
         }
         return ;
    }
    int main()
    {
         int t,n,i,j,h=1,b[N],a[N],c[N];
         cin>>t;
         while(t--)
         {
             scanf("%d",&n);
              for(i=1;i<=n;i++)
              {
                 scanf("%d",&a[i]);
              }
              creat(1,1,n);
              for(i=n;i>0;i--)
              {
                 if(a[i]==1)
                 b[i]=0;
                 else
                  b[i]=finds(1,1,n,1,a[i]-1);
                 updata(1,1,n,a[i]);
              }
              printf("Case #%d: ",h++);
              for(i=1;i<=n;i++)
              {
                 int k1=b[i]+i;
                 int k2=i;
                 int k3=a[i];
    
                  c[a[i]]=max(max(k1,k2),k3)-min(min(k1,k2),k3);
              }
              for(i=1;i<=n;i++)
              {
                    if(i==n)
                 printf("%d",c[i]);
                 else
                 printf("%d ",c[i]);
              }
              printf("
    ");
         }
         return 0;
    }
    

      

  • 相关阅读:
    你真的了解HTML吗?–雅虎面试题
    移动端meta 解释
    PLSQL导入导出表的正确步骤
    Linux命令学习之xargs命令
    python搭建简易Web Server
    python小项目练习之转换像素图片为字符图
    向量空间搜索引擎基本理论
    Elasticsearch 常用基本查询
    Elasticsearch配置参数介绍
    JavaWeb温习之防止表单重复提交
  • 原文地址:https://www.cnblogs.com/yuanbo123/p/5715572.html
Copyright © 2011-2022 走看看