AmazingCounters.com

NOIp2013火柴排队

背景

noip2013day1

数据来自官方

 

描述

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各
自 排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为:∑(ai-bi)2

其中 ai 表示第一列火柴中第 i 个火柴的高度, bi 表示第二列火柴中第 i 个火柴的高度。

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最
小。请问得到这个最小的距离,最少需要交换多少次? 如果这个数字太大,请输出这个最
小交换次数对 99,999,997 取模的结果。

输入格式

 

 

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

输出格式

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

测试样例1

输入


2 3 1 4 
3 2 1 4

输出

1

备注

 

对于 10%的数据, 1 ≤ n ≤ 10;
对于 30%的数据, 1 ≤ n ≤ 100;
对于 60%的数据, 1 ≤ n ≤ 1,000;
对于 100%的数据, 1 ≤ n ≤ 100,000, 0 ≤火柴高度≤ 231 − 1。

复习了树状数组及离散的相关知识。。

 

#include<set>
#include<queue>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100050;
const int MOD = 99999997;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,l,r) for(int i=l;i<=r;i++)

struct date{
    int v,id;
}A[N],B[N];

int sep[N],n,c[N],C[N];

int lowbit(int x){ return (x&(-x));}

void Modify(int loc,int num){
    while(loc<N){
        c[loc]+=num;c[loc]%=MOD;
        loc+=lowbit(loc);
    }
}

int Getsum(int loc){
    int sum=0;
    while(loc>0){
        sum+=c[loc];
        loc-=lowbit(loc);
        sum%=MOD;
    }
    return sum%MOD;
}

bool cmp(date A,date B){
    return A.v<B.v;
}

int main(){
    scanf("%d",&n);
    For(i,n) {scanf("%d",&A[i].v);A[i].id=i;}
    For(i,n) {scanf("%d",&B[i].v);B[i].id=i;}
    sort(A+1,A+n+1,cmp);
    sort(B+1,B+n+1,cmp);
    For(i,n) C[B[i].id]=A[i].id;
    int ans=0;
    For(i,n){
        Modify(C[i],1);
        ans=(ans%MOD+(i-Getsum(C[i]))%MOD)%MOD;
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

posted @ 2015-10-14 20:52  ZJDx1998  阅读(253)  评论(0编辑  收藏  举报