2013年NOIP提高组 火柴排队

来源:互联网 发布:淘宝售中流程 编辑:程序博客网 时间:2024/05/16 12:44

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:
这里写图片描述
,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

输入描述 Input Description
共三行,第一行包含一个整数 n,表示每盒中火柴的数目。
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出描述 Output Description
输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。

根据距离的定义,最小的距离应该是数列a的第 i 大数 与数列b的第 i 大数分别做差,离散化后就变成了 ai 与 bi 相等,即求数列 a 基于 数列 b 的逆序对个数。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int size = 100010;int num[size];int templ[size];int temp[size];int ans = 0;int n;int a[size],b[size];int cmp[size];const int mod = 99999997;int EF(int l,int r,int k,int *tmp){    while(r - l > 1)    {        int mid = (l + r) >> 1;        if(tmp[k] > templ[mid])            l = mid;        else if (tmp[k] < templ[mid])            r = mid;        else            return mid;    }    return r;}void lsha(){    for(int i = 1 ; i <= n ; i ++)        templ[i] = a[i];    sort( templ+1 , templ+n+1 );    for(int i = 1 ; i <= n ; i ++)        a[i] = EF(0,n+1,i,a);}void lshb(){    for(int i = 1 ; i <= n ; i ++)        templ[i] = b[i];    sort( templ+1 , templ+n+1 );    for(int i = 1 ; i <= n ; i ++)        b[i] = EF(0,n+1,i,b);}void merge(int l,int r){    if(l == r)        return ;    int mid = (l + r) >> 1;    merge(l,mid) , merge(mid+1,r);    int ll = l , rr = mid + 1 , p = ll;    while(ll <= mid || rr <= r)    {        if(rr > r || (ll <= mid && cmp[a[ll]] <= cmp[a[rr]]))            temp[p++] = a[ll++];        else        {            temp[p++] = a[rr++];            ans += mid - ll + 1;            ans %= mod;        }    }    for(int i = l ; i <= r ; i ++)        a[i] = temp[i];}int main(){    int n;    scanf("%d",&n);    for(int i = 1 ; i <= n ; i ++)        scanf("%d",&a[i]);    for(int i = 1 ; i <= n ; i ++)        scanf("%d",&b[i]);    lsha();    memset(templ,0,sizeof(templ));    lshb();    for(int i = 1 ; i <= n ; i ++)        cmp[b[i]] = i;    merge(1,n);    printf("%d",ans%mod);    return 0;}

传送门 :
codevs 3286
tyvj 2515

0 0
原创粉丝点击