线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop

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 = 5000 + 10;
int n, a[maxn];
struct node
{
    int l, r, num;
}tree[4*maxn];

void push_up(int id)
{
    tree[id].num = tree[id << 1].num + tree[id << 1 | 1].num;
}

void build(int id, int l, int r)
{
    tree[id].l = l;
    tree[id].r = r;
    if (l == r)
    {
        tree[id].num = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, 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) >> 1;
    int ans = 0;
    if (x <= mid) ans += query(x, y, id << 1);
    if (y > mid) ans += query(x, y, id << 1 | 1);
    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 = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) update(x, y, id << 1);
    if (y > mid) update(x, y, id << 1 | 1);
    push_up(id);
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        int sum = 0,ans=inf;
        build(1, 0, n - 1);
        for (int i = 0;i < n;i++)
        {
            
            scanf("%d", &a[i]);
            sum += query(a[i], n - 1, 1);
            update(a[i], a[i], 1);
            //debug(sum);
        }
        //debug(sum);
        for (int i = 0;i < n;i++)
        {
            sum = sum + (n - 1 - a[i]) - a[i];
            ans = min(sum, ans);
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

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 + 10;
typedef long long ll;
map<ll, ll>mp;
struct node
{
    int l, r;
    int sum;
}tree[4*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 = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, 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 = 0;
    int mid = (l + r) >> 1;
    if (x <= mid) ans += query(id << 1, x, y);
    if (y > mid) ans += query(id << 1 | 1, 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 << 1].sum + tree[id << 1 | 1].sum;
}

void update(int id,int x)
{
    int l = tree[id].l;
    int r = tree[id].r;
    if(l==r)
    {
        tree[id].sum = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) update(id << 1, x);
    else update(id << 1 | 1, x);
    push_up(id);
}


int main()
{
    int n, tot = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lld%lld", &a[i].first, &a[i].second);
    sort(a + 1, a + 1 + n, cmp1);
    for(int i=1;i<=n;i++)
    {
        if (mp[a[i].second]) continue;
        mp[a[i].second] = ++tot;
    }
    sort(a + 1, a + 1 + n, cmp);
    build(1, 1, tot);
    int ans = 0;
    for(int i=1;i<=n;i++)
    {
        if (query(1, mp[a[i].second], tot)) ans++;
        update(1, mp[a[i].second]);
    }
    printf("%d\n", ans);
    return 0;
}
/*
 6
100 100
90 100
90 100
80 90
80 90
70 100
 */
View Code

 

还有一个是选拔赛的题目,学校oj崩了,下次再写。

posted @ 2019-07-17 11:32  EchoZQN  阅读(105)  评论(0编辑  收藏  举报