线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop
Minimum Inversion Number
求最小反转数,就是求最少的逆序对。
逆序对怎么求,就是先把所有的数都初始化为0,然后按照顺序放入数字,放入数字前查询从这个数往后面的数的位置是不是被占了,被占了说明有逆序对。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define debug(n) printf("%d\n",n)
#define inf 0x3f3f3f3f;
using namespace std;
const int maxn = + ;
int n, a[maxn];
struct node
{
int l, r, num;
}tree[*maxn]; void push_up(int id)
{
tree[id].num = tree[id << ].num + tree[id << | ].num;
} void build(int id, int l, int r)
{
tree[id].l = l;
tree[id].r = r;
if (l == r)
{
tree[id].num = ;
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
push_up(id);
} int query(int x, int y, int id)
{
int l = tree[id].l;
int r = tree[id].r;
if (x <= l && y >= r)
{
return tree[id].num;
}
int mid = (l + r) >> ;
int ans = ;
if (x <= mid) ans += query(x, y, id << );
if (y > mid) ans += query(x, y, id << | );
push_up(id);
return ans;
} void update(int x, int y, int id)
{
int l = tree[id].l;
int r = tree[id].r;
if (x <= l && y >= r)
{
tree[id].num = ;
return;
}
int mid = (l + r) >> ;
if (x <= mid) update(x, y, id << );
if (y > mid) update(x, y, id << | );
push_up(id);
} int main()
{
while (scanf("%d", &n) != EOF)
{
int sum = ,ans=inf;
build(, , n - );
for (int i = ;i < n;i++)
{ scanf("%d", &a[i]);
sum += query(a[i], n - , );
update(a[i], a[i], );
//debug(sum);
}
//debug(sum);
for (int i = ;i < n;i++)
{
sum = sum + (n - - a[i]) - a[i];
ans = min(sum, ans);
}
printf("%d\n", ans);
}
return ;
}
对其中一个进行排序,转化成逆序对。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 2e5 + ;
typedef long long ll;
map<ll, ll>mp;
struct node
{
int l, r;
int sum;
}tree[*maxn];
pair<ll, ll>a[maxn];
bool cmp(pair<ll,ll>a,pair<ll,ll>b)
{
return a.first > b.first;
}
bool cmp1(pair<ll,ll>a,pair<ll,ll>b)
{
return a.second < b.second;
}
void build(int id, int l, int r) {
tree[id].l = l;
tree[id].r = r;
if (l == r) {
tree[id].sum = ;
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
} int query(int id,int x,int y)
{
int l = tree[id].l;
int r = tree[id].r;
if(x<=l&&y>=r)
{
// printf("id=%d sum=%d \n", id,tree[id].sum);
return tree[id].sum;
}
int ans = ;
int mid = (l + r) >> ;
if (x <= mid) ans += query(id << , x, y);
if (y > mid) ans += query(id << | , x, y);
// printf("id=%d ans=%d l=%d r=%d x=%d y=%d \n", id, ans, l, r,x,y);
return ans;
} void push_up(int id)
{
tree[id].sum = tree[id << ].sum + tree[id << | ].sum;
} void update(int id,int x)
{
int l = tree[id].l;
int r = tree[id].r;
if(l==r)
{
tree[id].sum = ;
return;
}
int mid = (l + r) >> ;
if (x <= mid) update(id << , x);
else update(id << | , x);
push_up(id);
} int main()
{
int n, tot = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%lld%lld", &a[i].first, &a[i].second);
sort(a + , a + + n, cmp1);
for(int i=;i<=n;i++)
{
if (mp[a[i].second]) continue;
mp[a[i].second] = ++tot;
}
sort(a + , a + + n, cmp);
build(, , tot);
int ans = ;
for(int i=;i<=n;i++)
{
if (query(, mp[a[i].second], tot)) ans++;
update(, mp[a[i].second]);
}
printf("%d\n", ans);
return ;
}
/*
6
100 100
90 100
90 100
80 90
80 90
70 100
*/
还有一个是选拔赛的题目,学校oj崩了,下次再写。
线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop的更多相关文章
- Minimum Inversion Number~hdu 1394
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...
- 【线段树】HDU1394 - Minimum Inversion Number
[题目大意] 给出0..n-1组成的一段数,可以移动前几个数到结尾.求出最小的逆序对个数. [思路] 先用线段树求出逆序对,方法和树状数组是一样的.然后对于当前第一个数num[0],在它之后比它小的数 ...
- HDU-1394 Minimum Inversion Number 线段树+逆序对
仍旧在练习线段树中..这道题一开始没有完全理解搞了一上午,感到了自己的shabi.. Minimum Inversion Number Time Limit: 2000/1000 MS (Java/O ...
- HDU 1394 (逆序数) Minimum Inversion Number
原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. #include <cstdio> #include <cstring> #in ...
- 线段树逆序对(偏序)——cf1187D好题!
/* 排除掉所有不可能的情况,剩下的就是可行的 1.数的数量不相同 2.对任意一个区间进行排序,等价于可以交换任意逆序对, 那么从1到n扫描b数组,判断是否可以将a数组中等于b[i]的值所在的位置j交 ...
- Petya and Array (权值线段树+逆序对)
Petya and Array http://codeforces.com/problemset/problem/1042/D time limit per test 2 seconds memory ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- 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(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
随机推荐
- Docker-CentOS系统安装Docker
上一节,我们介绍了安装虚拟机及操作系统,本文再详细描述安装docker的命令. 前提条件 虚拟机系统:CentOS,并且虚拟机能连通外网. 另外,虚拟机最好配置上阿里的镜像源,点此链接,进入cento ...
- C# 基础知识系列- 10 反射和泛型(二)
0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...
- 弹幕有点逗比,用 Python 爬下来看看《民国奇探》的弹幕
电视剧<民国奇探>是一部充斥着逗比风的探案剧,剧中主要角色:三土.四爷.白小姐,三土这个角色类似于<名侦探柯南>中的柯南但带有搞笑属性,四爷则类似于毛利小五郎但有大哥范且武功高 ...
- Java - window下环境配置
JDK下载 官网:https://www.oracle.com/java/technologies/javase-jdk8-downloads.html 百度网盘: 链接:https://pan.ba ...
- 21.SpringCloud实战项目-后台题目类型功能(网关、跨域、路由问题一文搞定)
SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...
- 从"UDF不应有状态" 切入来剖析Flink SQL代码生成
从"UDF不应有状态" 切入来剖析Flink SQL代码生成 目录 从"UDF不应有状态" 切入来剖析Flink SQL代码生成 0x00 摘要 0x01 概述 ...
- C语言如何实现继承及容器
继承的概念 继承是面向对象软件技术当中的一个概念,与多态.封装共为面向对象的三个基本特征.继承可以使得子类具有父类的属性和方法或者重新定义,追加属性和方法. 面向对象中的重要概念就是类,在我们熟知的编 ...
- appium同时运行两台真机
执行命令: appium -p 4494 -bp 2253 -U GWY0217207001793 appium -p 4493 -bp 2252 -U 77fdaabc server 设置:http ...
- php正则验证手机、邮箱
//验证电话private function reg_phone($phone){ if (preg_match("/^13[0-9]{1}[0-9]{8}$|15[0189] ...
- 一千行mysql笔记
原文地址:https://shockerli.net/post/1000-line-mysql-note/ /* Windows服务 */ -- 启动MySQL net start mysql -- ...