• hdu 1394


    这题就是给你一个数列,然后依次把开头的数移到最后,一直到又恢复原状,输出这些变化中最小的逆序数,我是先求出了最初的逆序数,然后后面可以用公式直接枚举出

    #include <iostream>
    #include <cstring>
    using namespace std;
    #define MAX 30000
    #define MAX_S 5001
    
    // hdu 1394
    typedef struct node
    {
     int s,e;
     int w;
     //int val;
     node (int a=0,int b=0,int c=0):s(a),e(b),w(c){}
    }node;
    int arr[MAX_S];
    node tree[MAX];
    int flag=0;
    //在这里是 用 【4,6】这样的线段表示,4,5,6,那么如果输入3,我们查找时就到 3+1开始的区间, 
    void build (int T,int s,int e)  //该区间就表示了比三大的数目有多少 
    {
       if (s == e)
        {
          tree[T] = node (s,e,0);
        }
       else
       {
            int mid = (s+e)>>1;
            build (T<<1,s,mid);
            build (T<<1|1,mid+1,e);
            tree[T] = node(s,e,0);
       }
    }
    
    //查找大于a[i]的元素,在【a[i]+1,n-1】区间中,查找,因为,如果前面输入的数有大于a[i] 
    int Query(int T,int s,int e)//的,那么一定会被更新到对应的区间,所以你在 [a[i]+1,n-1]
    {                                 //区间查找,便一定能找到对应的逆序数个数 
      if (s <= tree[T].s && tree[T].e <=e)
        return tree[T].w;
      int mid = (tree[T].s+tree[T].e)>>1;
      int s1 =0,s2=0;
      if (s<=mid)
        s1  = Query(T<<1,s,e);
      if (e>mid)
        s2  = Query(T<<1|1,s,e);
      return s1+s2;
    }
    
    //一直递归直到找到 e 号节点,使该节点的W值为1,于是下一次查询时,如果是小于e的数 
    void update (int T,int e) //那么一定会找到e 号节点,从而逆序数加一
    { 
       if (tree[T].s == e && tree[T].e == e)
         {
            tree[T].w=1;
            return ;
         }
       int mid = (tree[T].s+tree[T].e)>>1;
       if (e<=mid)
         update(T<<1,e);
       else
         update(T<<1|1,e);
        tree[T].w = tree[T<<1].w+tree[T<<1|1].w;
    }
    
    
    int main ()
    {
      std::ios::sync_with_stdio(false);
      int n;
     while(cin>>n)
     {
          build(1,0,n-1);
          int ans = 0;
       for (int i=0;i<n;++i)
         {
          cin>>arr[i];
          ans +=Query(1,arr[i]+1,n-1);
          update(1,arr[i]);
         }
          int min = ans;
          //公式 
         for (int i=0;i<n;++i)
         {
             ans = ans +n-1-2*arr[i];
             if (min > ans)
              min =ans;
         }
         cout<<min<<endl;
     }
     return 0;
    }
    
    /*
    10
    1 3 6 9 0 8 5 7 4 2
    */
  • 相关阅读:
    注释
    选择器
    SQL语句中查找字符的位置
    SQL语句中截取字符串Substr
    IDENTITY(函数)
    SQL Server设置主键自增长列
    SQL语句操作ALTER
    表的主键
    南京夜市
    夜班
  • 原文地址:https://www.cnblogs.com/yuluoluo/p/8047758.html
Copyright © 2020-2023  润新知