• 线段树解Insertion Sort Advanced Analysis


    题目出处

    题意描述:

    这个题目提问的是,在插入排序的序列给定的情况下,求最少需要移动的次数。

    序列的长度n <=10^5

    序列中的元素a[i] <=10^6

    一组数据中case数t <=5

    题目分析:

    这个题,拿到题目一眼望去满满的都是暴力的影子(又傻逼了)。

    然后仔细分析一下暴力的复杂度,每插入一个元素都要扫过一边数组,显而易见的O(n*n),TLE思密达。

    然后再认真分析一下题目,所求最少的移动次数,也就是说:对于其中任意一个元素a[i],只需要求出从a[1]到a[i-1]中大于a[i]的数字的数量。

    说白了就是逆序数。。。

    之后就是寻找一种数据结构或者算法可以在o(n)更短的时间内求出逆序数

    动手:

    线段树和树状数组十分适合这题,于是研习一下百度搜到的神牛的代码,迅速山寨了一个线段树的代码。

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <cstring>
      7 using namespace std;
      8 
      9 const int MAXN = 1000000+5;
     10 
     11 struct Node{
     12     int a,b,left,right,val;
     13 };
     14 
     15 Node tree[MAXN*2];
     16 int L = 0;
     17 int a[100000+5];
     18 
     19 void B( int x, int y ){
     20     //cout<<x<<"  "<<y<<endl;
     21     int This = L;
     22     tree[This].a = x;
     23     tree[This].b = y;
     24     tree[This].val = 0;
     25     if ( y - x >= 1 ){
     26         int mid = (x+y)/2;
     27         L++;
     28         tree[This].left = L;
     29         B(x,mid);
     30         L++;
     31         tree[This].right = L;
     32         B(mid+1,y);
     33     }
     34     //cout<<"DONE "<<x<<" "<<y<<endl;
     35 }
     36 
     37 void I( int x, int y, int t ){
     38     //cout<<"I "<<x<<" "<<y<<" "<<t<<endl;
     39     if ( ( x <= tree[t].a ) && ( y >= tree[t].b ) ){
     40         tree[t].val++;
     41     }else{
     42         tree[t].val++;
     43         int mid = (tree[t].a+tree[t].b)/2;
     44         if ( x <= mid ){
     45             I(x,y,tree[t].left);
     46         }
     47         if ( y >= mid+1 ){
     48             I(x,y,tree[t].right);
     49         }
     50     }
     51 }
     52 
     53 int S( int x, int y, int t ){
     54     if ( tree[t].val == 0 ){
     55         return 0;
     56     }
     57     if ( ( x<= tree[t].a )  && ( y >= tree[t].b ) ){
     58         return tree[t].val;
     59     }else{
     60     int mid = (tree[t].a+tree[t].b)/2;
     61     int ans = 0;
     62     if ( x <= mid ){
     63         ans += S(x,y,tree[t].left);
     64     }
     65     if ( y >= mid+1 ){
     66         ans += S(x,y,tree[t].right);
     67     }
     68     return ans;
     69     }
     70 }
     71 
     72 int G( int x, int y ){
     73     return S(0,y,0)-S(0,x,0);
     74 }
     75 
     76 void show(int k){
     77     for ( int i = 0; i<= k; i++ ){
     78     cout<<i<<" f "<<tree[i].a<<" t "<<tree[i].b<<"  "<<tree[i].left<<"  "<<tree[i].right<<"  "<<tree[i].val<<endl;
     79 }
     80 }
     81 
     82 void solve(){
     83     int n;
     84     cin>>n;
     85     int i = 0;
     86     int MAX = 0;
     87     long long ans = 0;
     88     int MIN = 1000000+10;
     89     memset(a,0,sizeof(a));
     90     for ( i = 0; i < n; i++ ){
     91         cin>>a[i];
     92         if ( MAX < a[i] ){
     93             MAX = a[i];
     94         }
     95         if ( MIN > a[i] ){
     96             MIN = a[i];
     97         }
     98     }
     99     //cout<<MAX<<endl;
    100     //cout<<MIN<<endl;
    101     B(MIN-1,MAX);
    102     //show(L);
    103     //cout<<"sb"<<endl;
    104     for ( i = 0; i < n; i++ ){
    105         I(a[i],a[i],0);
    106         ans += G(a[i],MAX);
    107     }
    108     cout<<ans<<endl;
    109 }
    110 
    111 
    112 int main() {
    113     int t;
    114     int i;
    115     cin>>t;
    116     for ( i = 0; i <t; i++ ){
    117         L = 0;
    118         solve();
    119     }
    120     return 0;
    121 }
    线段树

    想起来个要命的事儿就是用python3写会超时,可能是python内部开内存的方式比较慢,不像C++写在外面,是直接开出来的。

    这题后来拿给狗哥做了一发,结果用了个树状数组就给我平了,,,虽然差不大多,但是代码量要小很多,看来需要研习一下了。

  • 相关阅读:
    威胁情报网站
    python3实现telnet查看IP地址段端口开放情况
    python3实现指定IP多线程端口扫描
    安全网址导航
    python3调用exe程序编写cve20190708批量检测工具
    python3爬取网页中的邮箱地址
    黑客马拉松
    Nginx自定义模块编写:根据post参数路由到不同服务器
    Apache HTTP Server 与 Tomcat 的三种连接方式介绍
    Apache HTTP Server 与 Tomcat 的三种连接方式介绍
  • 原文地址:https://www.cnblogs.com/qoshi/p/3329568.html
Copyright © 2020-2023  润新知