• 多校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;
    }
    

      

  • 相关阅读:
    人民币对美元汇率的大数据分析与预测【完整代码】
    碧瑶答疑网——用户使用手册和反馈
    碧瑶答疑网—系统设计和任务分配
    碧瑶答疑网之选题报告
    碧瑶答疑网-软件需求规格说明书
    UEgCWbGGLA
    https://www.cnblogs.com/ggzjf/
    66666
    继承-代码块-接口
    人民币对澳元汇率的大数据分析与预测
  • 原文地址:https://www.cnblogs.com/yuanbo123/p/5715572.html
Copyright © 2020-2023  润新知