线段树解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)--这样就能通 ...
随机推荐
- 0_Linux_虚拟机安装
虚拟机的安装0Snapshot和clone 系统分区(由硬盘的性能所限制的) 1分区类型: 主分区:最多有4个 扩展分区:最多只能有1个:主分区加扩展分区最多有4个:不能写入数据,只能包含逻辑分区,不 ...
- zoj 3537 Cake(区间dp)
这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三 ...
- codevs 1994 排队 排列组合+高精度
/* 数学题0.0 最后答案:A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1); 简单解释一下 +之前的很显然 先排男 ...
- (转)Div左右两侧等高
一. 利用背景图,做出左右等高的模拟效果 这种方法不是真正的左右等高,而是在外框元素中添加一张背景图片,当内容增多时,背景会纵向重复,就会形成左右等高的效果. 这种方法不是真正的div自动等高,而 ...
- (转)PHP自定义遍历目录下所有文件dir(),readdir()函数
方法一:使用dir()遍历目录 dir()函数,成功时返回Directory类实例 PHP dir() 语法格式为: dir(directory);//directory为需要显示文件名的目录名称,可 ...
- 巧妙的Jq仿QQ游戏导航界面学习
先贴上源代码 <!doctype html> <html> <head> <meta charset="utf-8"> <ti ...
- iOS学习笔记(十四)——打电话、发短信
电话.短信是手机的基础功能,iOS中提供了接口,让我们调用.这篇文章简单的介绍一下iOS的打电话.发短信在程序中怎么调用. 1.打电话 [[UIApplication sharedApplicatio ...
- Hibernate 持久化对象的状态
持久化对象有3种状态:1.持久化状态 2.临时状态 3.游离状态 Session 的特定方法能使对象从一个状态转换到另一个状态临时对象(transient)• 在使用代理主键 ...
- 网络编程Socket之TCP
服务端: 1. 创建 ServerSocket 对象并监听一个端口 2. 调用accept()方法等待客户端的连接(阻塞式) 3. 输入流(记取客户端发送过来的数据) 4. 输出流(响 ...
- GetComponents和FindObjectsOfTypeAll区别
本文由博主(YinaPan)原创,转载请注明出处:http://www.cnblogs.com/YinaPan/p/Unity_GetComponent.html GetComponents获得的是当 ...