hdu1394 Minimum Inversion Number(单点更新)

来源:互联网 发布:汉王考勤软件下载 编辑:程序博客网 时间:2024/06/02 04:19


不得不说,线段树太神奇了,居然还可以这么玩。。。


题意:首先知道什么是最小逆序数对


#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;typedef long long LL;const int N = 5010;const int INF = 1e8;struct line{    int l;    int r;    int value;}tree[4 * N];int a[N];void build(int i, int l, int r){    tree[i].l = l;    tree[i].r = r;    tree[i].value = 0;    if(l == r) return;    int mid = (l + r) >> 1;    build(i*2, l, mid);    build(i*2+1, mid+1, r);}int query(int i, int l, int r){    if(tree[i].l == l && tree[i].r == r)    {        return tree[i].value;    }    int mid = (tree[i].l + tree[i].r) >> 1;    if(mid >= r) return query(i*2, l, r);    else if(mid < l) return query(i*2+1, l, r);    else return (query(i*2, l, mid) + query(i*2+1, mid+1, r));}void update(int i, int x){    if(tree[i].l <= x && tree[i].r >= x)    {        tree[i].value++;    }    if(tree[i].l == tree[i].r)    {        return;    }    int mid = (tree[i].l + tree[i].r) >> 1;    if(mid >= x) update(i*2, x);    else update(i*2+1, x);}int main(){   // freopen("in.txt", "r", stdin);    int num, n, t;    while(~scanf("%d", &n))    {        build(1, 0, n-1);        int ans = 0;        for(int i = 0; i < n; i++)        {            scanf("%d", &a[i]);            if(i != 0 && a[i] != n-1)            {                ans += query(1, a[i]+1, n-1);            }            update(1, a[i]);        }        int res = ans;        for(int i = 0; i < n; i ++)        {            ans += n-1-2*a[i];            if(ans < res) res = ans;        }        printf("%d\n", res);    }    return 0;}


0 0
原创粉丝点击