线段树解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)更短的时间内求出逆序数
动手:
线段树和树状数组十分适合这题,于是研习一下百度搜到的神牛的代码,迅速山寨了一个线段树的代码。
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = +; struct Node{
int a,b,left,right,val;
}; Node tree[MAXN*];
int L = ;
int a[+]; void B( int x, int y ){
//cout<<x<<" "<<y<<endl;
int This = L;
tree[This].a = x;
tree[This].b = y;
tree[This].val = ;
if ( y - x >= ){
int mid = (x+y)/;
L++;
tree[This].left = L;
B(x,mid);
L++;
tree[This].right = L;
B(mid+,y);
}
//cout<<"DONE "<<x<<" "<<y<<endl;
} void I( int x, int y, int t ){
//cout<<"I "<<x<<" "<<y<<" "<<t<<endl;
if ( ( x <= tree[t].a ) && ( y >= tree[t].b ) ){
tree[t].val++;
}else{
tree[t].val++;
int mid = (tree[t].a+tree[t].b)/;
if ( x <= mid ){
I(x,y,tree[t].left);
}
if ( y >= mid+ ){
I(x,y,tree[t].right);
}
}
} int S( int x, int y, int t ){
if ( tree[t].val == ){
return ;
}
if ( ( x<= tree[t].a ) && ( y >= tree[t].b ) ){
return tree[t].val;
}else{
int mid = (tree[t].a+tree[t].b)/;
int ans = ;
if ( x <= mid ){
ans += S(x,y,tree[t].left);
}
if ( y >= mid+ ){
ans += S(x,y,tree[t].right);
}
return ans;
}
} int G( int x, int y ){
return S(,y,)-S(,x,);
} void show(int k){
for ( int i = ; i<= k; i++ ){
cout<<i<<" f "<<tree[i].a<<" t "<<tree[i].b<<" "<<tree[i].left<<" "<<tree[i].right<<" "<<tree[i].val<<endl;
}
} void solve(){
int n;
cin>>n;
int i = ;
int MAX = ;
long long ans = ;
int MIN = +;
memset(a,,sizeof(a));
for ( i = ; i < n; i++ ){
cin>>a[i];
if ( MAX < a[i] ){
MAX = a[i];
}
if ( MIN > a[i] ){
MIN = a[i];
}
}
//cout<<MAX<<endl;
//cout<<MIN<<endl;
B(MIN-,MAX);
//show(L);
//cout<<"sb"<<endl;
for ( i = ; i < n; i++ ){
I(a[i],a[i],);
ans += G(a[i],MAX);
}
cout<<ans<<endl;
} int main() {
int t;
int i;
cin>>t;
for ( i = ; i <t; i++ ){
L = ;
solve();
}
return ;
}
线段树
想起来个要命的事儿就是用python3写会超时,可能是python内部开内存的方式比较慢,不像C++写在外面,是直接开出来的。
这题后来拿给狗哥做了一发,结果用了个树状数组就给我平了,,,虽然差不大多,但是代码量要小很多,看来需要研习一下了。
线段树解Insertion Sort Advanced Analysis的更多相关文章
- 【HackerRank】Insertion Sort Advanced Analysis(归并排序求数列逆序数对)
Insertion Sort is a simple sorting technique which was covered in previous challenges. Sometimes, ar ...
- 线段树解LIS
先是nlogn的LIS解法 /* LIS nlogn解法 */ #include<iostream> #include<cstring> #include<cstdio& ...
- cf1132G 线段树解分区间LIS(一种全新的线段树解LIS思路)+单调栈
/* 给定n个数的数列,要求枚举长为k的区间,求出每个区间的最长上升子序列长度 首先考虑给定n个数的数列的LIS求法:从左往右枚举第i点作为最大点的贡献, 那么往左找到第一个比a[i]大的数,设这个数 ...
- POJ - 3264 Balanced Lineup 线段树解RMQ
这个题目是一个典型的RMQ问题,给定一个整数序列,1~N,然后进行Q次询问,每次给定两个整数A,B,(1<=A<=B<=N),求给定的范围内,最大和最小值之差. 解法一:这个是最初的 ...
- 1521. War Games 2(线段树解约瑟夫)
1521 根据区间和 来确定第k个数在哪 #include <iostream> #include<cstdio> #include<cstring> #inclu ...
- poj2299--B - Ultra-QuickSort(线段树,离散化)
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 41215 Accepted: 14915 ...
- hdu 1394 Minimum Inversion Number(这道题改日我要用线段树再做一次哟~)
Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...
- cf842D 01字典树|线段树 模板见hdu4825
一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了 下面的代码是逆向建树的,数据量大就不行 /*3 01字典树 根据异或性质,a1!=a2 ==> a1^x1^..^ ...
- 816B. Karen and Coffee 前缀和思维 或 线段树
LINK 题意:给出n个[l,r],q个询问a,b,问被包含于[a,b]且这样的区间数大于k个的方案数有多少 思路:预处理所有的区间,对于一个区间我们标记其(左边界)++,(右边界+1)--这样就能通 ...
随机推荐
- Audio Capture 录音
The Android multimedia framework includes support for capturing and encoding a variety of common aud ...
- ansible小结
一.Ansible的安装 1.yum源安装 以centos为例,默认在源里没有ansible,不过在fedora epel源里有ansible,配置完epel 源后,可以直接通过yum 进行安装.这里 ...
- 使用ssh对服务器进行登录
一.什么是SSH? 简单说,SSH是一种网络协议,用于计算机之间的加密登录. 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会 ...
- codevs 1997 守卫者的挑战
/* 表示很遗憾.. 开始状态想的没错 就是转移的时候出了问题 自己也想到了数组平移 然而没往下写 与正解擦肩而过…. 然后为了好转移写了个4维的 时间不多了没来得及降维 草草的算算空间就交了… 尼玛 ...
- Spring配置静态目录
mvc-dispatcher-servlet.xml文件 <beans xmlns="http://www.springframework.org/schema/beans" ...
- 图解MonoForAndroid开发环境搭建
电脑系统:windows 8.1 企业版 预装VS:2010旗舰版+2013 with update2旗舰版 ==================================== 1.1 安装ja ...
- 如何修改UITableView每个cell的分隔线和左边的距离?
在ios7中,UITableViewCell左侧会有默认15像素的空白.这时候,设置setSeparatorInset:UIEdgeInsetsZero 能将空白去掉.但是在ios8中,设置setSe ...
- AMD和CMD的区别
1.cmd define(function(require,export){ var b = 1; var a = require('./a'); a.dosomething(); }); 2.amd ...
- Neutron/ML2学习
Neutron/ML2 Neutron ML2 模块层2(ml2)插件是一种允许OpenStack网络同时地利用在复杂现实数据中心发现的各种第二层网络技术的框架.目前它与存在的openvswitch. ...
- C++封装常用对象和对头文件探索
在C++实际开发中,难免会使用到一些你极为常用的算法(比如笔者经常使用的多线程技术),实现这些算法的类或是全局函数或是命名空间等等经常都要被使用多次,你会有哪些办法来使用呢?笔者有4个办法. 第一个方 ...