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. go中的error小结

    go中的error error和panic error接口 go中err的困局 推荐方法 总结 参考 go中的error go中的错误处理,是通过返回值的形式来出来,要么你忽略,要么你处理(处理也可以 ...

  2. 将class 编译后文件内容输入到 文本文件中的命令

    javap -c InnerTest$1 > InnerTest$1.txt

  3. mysql 向上取整

    SELECT CEILING(10.0)    --->10 SELECT CEILING(10.1)    --->11

  4. 使用SVGDeveloper画svg地图详细过程

    使用步骤 1.  安装svg 2.  具体操作 1.     打开svg,点击file ,new,默认svg,点击ok 显示界面如下: 然后点击image 把鼠标放到代码下面的的桌面上,鼠标箭头会变成 ...

  5. H - Knight Moves DFS

    A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the sh ...

  6. 详解 Collections类

    (请关注 本人"集合总集篇"博文--<详解 集合框架>) 有的同学可能会有这样的疑问 -- Collections类也是集合吗? 答曰:非也! 那为什么要讲解这个类呢? ...

  7. SUCTF 2019 Upload labs 2 踩坑记录

    SUCTF 2019 Upload labs 2 踩坑记录 题目地址 : https://github.com/team-su/SUCTF-2019/tree/master/Web/Upload La ...

  8. pytorch 孪生神经网络DNN

    代码内容请见: https://github.com/LiuXinyu12378/DNN-network

  9. python os模块获取指定目录下的文件列表

    bath_path = r"I:\ner_results\ner_results" dir_list1 = os.listdir(bath_path) for dir1 in di ...

  10. Java 多线程 -- 协作模型:生产消费者实现方式二:信号灯法

    使用信号灯法实现生产消费者模式需要借助标志位. 下面以演员表演,观众观看电视为列,写一个demo 同一资源 电视: //同一资源 电视 class Tv { String voice; // 信号灯 ...