Minimum Inversion Number

HDU - 1394

求最小反转数,就是求最少的逆序对。

逆序对怎么求,就是先把所有的数都初始化为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 ;
}

Laptop

对其中一个进行排序,转化成逆序对。

#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的更多相关文章

  1. Minimum Inversion Number~hdu 1394

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  2. 【线段树】HDU1394 - Minimum Inversion Number

    [题目大意] 给出0..n-1组成的一段数,可以移动前几个数到结尾.求出最小的逆序对个数. [思路] 先用线段树求出逆序对,方法和树状数组是一样的.然后对于当前第一个数num[0],在它之后比它小的数 ...

  3. HDU-1394 Minimum Inversion Number 线段树+逆序对

    仍旧在练习线段树中..这道题一开始没有完全理解搞了一上午,感到了自己的shabi.. Minimum Inversion Number Time Limit: 2000/1000 MS (Java/O ...

  4. HDU 1394 (逆序数) Minimum Inversion Number

    原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. #include <cstdio> #include <cstring> #in ...

  5. 线段树逆序对(偏序)——cf1187D好题!

    /* 排除掉所有不可能的情况,剩下的就是可行的 1.数的数量不相同 2.对任意一个区间进行排序,等价于可以交换任意逆序对, 那么从1到n扫描b数组,判断是否可以将a数组中等于b[i]的值所在的位置j交 ...

  6. Petya and Array (权值线段树+逆序对)

    Petya and Array http://codeforces.com/problemset/problem/1042/D time limit per test 2 seconds memory ...

  7. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  8. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  9. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

随机推荐

  1. Docker-CentOS系统安装Docker

    上一节,我们介绍了安装虚拟机及操作系统,本文再详细描述安装docker的命令. 前提条件 虚拟机系统:CentOS,并且虚拟机能连通外网. 另外,虚拟机最好配置上阿里的镜像源,点此链接,进入cento ...

  2. C# 基础知识系列- 10 反射和泛型(二)

    0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...

  3. 弹幕有点逗比,用 Python 爬下来看看《民国奇探》的弹幕

    电视剧<民国奇探>是一部充斥着逗比风的探案剧,剧中主要角色:三土.四爷.白小姐,三土这个角色类似于<名侦探柯南>中的柯南但带有搞笑属性,四爷则类似于毛利小五郎但有大哥范且武功高 ...

  4. Java - window下环境配置

    JDK下载 官网:https://www.oracle.com/java/technologies/javase-jdk8-downloads.html 百度网盘: 链接:https://pan.ba ...

  5. 21.SpringCloud实战项目-后台题目类型功能(网关、跨域、路由问题一文搞定)

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  6. 从"UDF不应有状态" 切入来剖析Flink SQL代码生成

    从"UDF不应有状态" 切入来剖析Flink SQL代码生成 目录 从"UDF不应有状态" 切入来剖析Flink SQL代码生成 0x00 摘要 0x01 概述 ...

  7. C语言如何实现继承及容器

    继承的概念 继承是面向对象软件技术当中的一个概念,与多态.封装共为面向对象的三个基本特征.继承可以使得子类具有父类的属性和方法或者重新定义,追加属性和方法. 面向对象中的重要概念就是类,在我们熟知的编 ...

  8. appium同时运行两台真机

    执行命令: appium -p 4494 -bp 2253 -U GWY0217207001793 appium -p 4493 -bp 2252 -U 77fdaabc server 设置:http ...

  9. php正则验证手机、邮箱

    //验证电话private function reg_phone($phone){        if (preg_match("/^13[0-9]{1}[0-9]{8}$|15[0189] ...

  10. 一千行mysql笔记

    原文地址:https://shockerli.net/post/1000-line-mysql-note/ /* Windows服务 */ -- 启动MySQL net start mysql -- ...