HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
题意分析
给出n个数的序列,a1,a2,a3……an,ai∈[0,n-1],求环序列中逆序对最少的个数。
前置技能
环序列
还
线段树的逆序对求法
- 逆序对:ai > aj 且 i < j ,换句话说数字大的反而排到前面(相对后面的小数字而言)
- 环序列:把第一个放到最后一个数后面,就是一次成环,一个含有n个元素序列有n个环序列。
- 线段树的逆序对求法:每个叶子节点保存的是当前值数字的个数。根据给出的数字,我们一次放入线段树,在放入的时候,其实考虑的是,当前线段树中比该数字大的数字个数有多少,这可以通过查询操作完成。然后我们放入线段树,每次都进行这样的操作,就可以得出一个序列的,逆序对个数。
每次进行成环的时候,就不用这么考虑了,对于一个序列,我们假设共有n个数字,并且当前的逆序对个数为k,对于第一个数字a,有t个数字小于a,可以计算得出有n-t-1个数字大于a。所以当我们把数字a移动到序列末端的时候,比他小的都成为了逆序对,比他大的都不是逆序对,此时的逆序对数目为k-t+n-t-1。
恰好此题中x[i]的值就是比他小的数字的个数,如此就可以通过简单循环完成。
代码总览
#include <bits/stdc++.h>
#define maxn 200010
#define NumMax 5000
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
int Sum[maxn<<2],Lazy[maxn<<2];
int x[maxn];
int N;
void PushUp(int rt){
Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
}
void Build(int l,int r,int rt){
if(l==r) {
Sum[rt] = 0;
return;
}
int m=(l+r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
PushUp(rt);
}
void UpdatePoint(int L,int l,int r,int rt){
if(l==r){
Sum[rt]++;
return;
}
int m=(l+r)>>1;
if(L <= m) UpdatePoint(L,l,m,rt<<1);
else UpdatePoint(L,m+1,r,rt<<1|1);
PushUp(rt);
}
void PushDown(int rt,int ln,int rn){
if(Lazy[rt]){
Lazy[rt<<1] = Lazy[rt];
Lazy[rt<<1|1] = Lazy[rt];
Sum[rt<<1] = Lazy[rt]*ln;
Sum[rt<<1|1] = Lazy[rt]*rn;
Lazy[rt]=0;
}
}
void UpdateInterval(int L,int R,int C,int l,int r,int rt){
if(L <= l && r <= R){
Sum[rt] = C*(r-l+1);
Lazy[rt] = C;
return ;
}
int m=(l+r)>>1;
PushDown(rt,m-l+1,r-m);
if(L <= m) UpdateInterval(L,R,C,l,m,rt<<1);
if(R > m) UpdateInterval(L,R,C,m+1,r,rt<<1|1);
PushUp(rt);
}
int Query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return Sum[rt];
}
int m = (l+r)>>1;
PushDown(rt,m-l+1,r-m);
int ANS = 0;
if(L <= m) ANS += Query(L,R,l,m,rt<<1);
if(R > m) ANS += Query(L,R,m+1,r,rt<<1|1);
return ANS;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&N)!=EOF){
int sum = 0;
Build(0,N-1,1);
for(int i = 0;i<N;++i){
scanf("%d",&x[i]);
sum+= Query(x[i]+1,N-1,0,N-1,1);
UpdatePoint(x[i],0,N-1,1);
}
int ans = sum;
for(int i = 0;i<N;++i){
sum = sum+N-2*x[i]-1;
ans = min(sum,ans);
}
printf("%d\n",ans);
}
return 0;
}
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)的更多相关文章
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- hdu - 1394 Minimum Inversion Number(线段树水题)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
- [HDU] 1394 Minimum Inversion Number [线段树求逆序数]
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...
- HDU 1394 Minimum Inversion Number 线段树
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...
- hdu 1166线段树 单点更新 区间求和
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- hdu1166(线段树单点更新&区间求和模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:中文题诶- 思路:线段树单点更新,区间求和模板 代码: #include <iost ...
- HDU 1394 Minimum Inversion Number (树状数组)
题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...
随机推荐
- mybatis拦截器使用
目录 mybatis 拦截器接口Interceptor spring boot + mybatis整合 创建自己的拦截器MyInterceptor @Intercepts注解 mybatis拦截器入门 ...
- 学习笔记之ubuntu修改固定IP脚本
一.shell脚本编程 二.正则表达式 三.linux修改IP的方法 #!/bin/bash cd /etc/network/ stty erase '^?' write_interfaces() { ...
- 高可用Kubernetes集群-5. 部署flannel网络
七.部署flannel网络 kubernetes支持基于vxlan方式的flannel与weave网络,基于BGP路由的Calico网络,本节采用flannel网络. Flannel网络采用etcd等 ...
- 基于日志报警插件 elastalert 实现告警
1.官方http://elastalert.readthedocs.io/en/latest/ 2.报警规则示例 http://elastalert.readthedocs.io/en/latest/ ...
- LibLas学习笔记
LibLas学习笔记 las 什么是Las格式 LAS文件格式是数据用户之间交换三维点云数据的公共文件格式. 虽然这种格式主要用于交换激光雷达点云数据,但是它支持交换任何三维的x.y.z 数组. 这 ...
- 当Kubernets遇上阿里云 -之七层负载均衡(一).
我们知道Kubernetes的service只能实现基于4层的负载均衡,无法提供7层之上的许多特性,诸如基于URL的负载均衡,SSL支持,三方授权等等:Ingress可以实现七层负载均衡的许多功能,唯 ...
- 使用Node.js 搭建http服务器 http-server 模块
1. 安装 http-server 模块 npm install http-server -g 全局安装 2.在需要的文件夹 启动 http-server 默认的端口是8080 可以使 ...
- P4tutorial实战
Tutorial样例实战 GitHub仓库地址 参考博客 实验一:SIGCOMM_2015/Sourse_Routing 实验环境: OS:Ubuntu16.04 bmv2:behavioral-mo ...
- OC创建对象并访问成员变量
1.创建一个对象 Car *car =[Car new] 只要用new操作符定义的实体,就会在堆内存中开辟一个新空间 [Car new]在内存中 干了三件事 1)在堆中开辟一段存储空间 2)初始化成员 ...
- 解决:Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986
目录 背景 原因分析 处理方法 参考 背景 在将tomcat升级到7.0.81版后,发现系统的有些功能不能使用了,查询日志发现是有些地址直接被tomcat认为存在不合法字符,返回HTTP 400错误响 ...