[树状数组+逆序对][NOIP2013]火柴排队
火柴排队
题目描述
涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,...,n。其中ai表示第一列火柴中第i个火柴的高度,bi表示第二列火柴中第 i个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对99,999,997取模的结果。
【输入输出样例1】
match.in
4
2 3 1 4
3 2 1 4
match.out
1
【输入输出样例说明】
最小距离是0,最少需要交换 1次,比如:交换第1 列的前2根火柴或者交换第 2列的前2根火柴。
【输入输出样例2】
match.in
4
1 3 4 2
1 7 2 4
match.out
2
【输入输出样例说明】
最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第2列中后2根火柴的位置。
输入
输入文件为match.in。
共三行,第一行包含一个整数 n,表示每盒中火柴的数目。
第二行有n个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有n个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
输出
输出文件为match.out。
输出共一行,包含一个整数,表示最少交换次数对99,999,997取模的结果。
提示
【数据范围】
对于10%的数据, 1 ≤ n ≤ 10;
对于30%的数据,1 ≤ n ≤ 100;
对于60%的数据,1 ≤ n ≤ 1,000;
对于100%的数据,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 231 − 1。
树状数组+逆序对裸题
代码:
1 #include<algorithm> 2 #include<cstdio> 3 #include<cstring> 4 5 const int Mod = 99999997, Maxv = 100005; 6 int rk[Maxv], t[Maxv], n, ans; 7 8 int read(){ 9 int x = 0, f = 1; 10 char ch = getchar(); 11 while (ch < '0' || ch > '9') { 12 if (ch == '-') { 13 f = -1; 14 } 15 ch = getchar(); 16 } 17 while (ch >= '0' && ch <= '9') { 18 x = x * 10 + ch - '0'; 19 ch = getchar(); 20 } 21 return x * f; 22 } 23 24 struct data{ 25 int v, num; 26 }a[Maxv], b[Maxv]; 27 28 bool cmp1(data x, data y){ 29 return x.v < y.v; 30 } 31 32 int lowbit(int x){ 33 return x & -x; 34 } 35 36 int query(int x){ 37 int tmp = 0; 38 for (int i = x; i; i -= lowbit(i)) { 39 tmp = (tmp + t[i]) % Mod; 40 } 41 return tmp; 42 } 43 44 void push_up(int x){ 45 for (int i = x; i <= n; i += lowbit(i)) { 46 t[i]++; 47 } 48 } 49 50 int main(){ 51 n = read(); 52 for (int i = 1; i <= n; i++) { 53 a[i].v = read(); 54 a[i].num = i; 55 } 56 for (int i = 1; i <= n; i++) { 57 b[i].v = read(); 58 b[i].num = i; 59 } 60 std::sort(a + 1, a + n + 1, cmp1); 61 std::sort(b + 1, b + n + 1, cmp1); 62 for (int i = 1; i <= n; i++) { 63 rk[a[i].num] = b[i].num; 64 } 65 for (int i = 1; i <= n; i++) { 66 push_up(rk[i]); 67 ans = (ans + i - query(rk[i])) % Mod; 68 } 69 printf("%d", ans); 70 return 0; 71 }