1010 Lehmer Code (35 分)(C++)

歡迎訪問我的PAT頂級題解目錄

According to Wikipedia: "In mathematics and in particular in combinatorics, the Lehmer code is a particular way to encode each possible permutation of a sequence of n numbers." To be more specific, for a given permutation of items {A​1​​, A​2​​, ⋯, A​n​​}, Lehmer code is a sequence of numbers {L​1​​, L​2​​, ⋯, L​n​​} such that L​i​​ is the total number of items from A​i​​ to A​n​​ which are less than A​i​​. For example, given { 24, 35, 12, 1, 56, 23 }, the second Lehmer code L​2​​ is 3 since from 35 to 23 there are three items, { 12, 1, 23 }, less than the second item, 35.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤10​5​​). Then N distinct numbers are given in the next line.

Output Specification:

For each test case, output in a line the corresponding Lehmer code. The numbers must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

6
24 35 12 1 56 23

Sample Output:

3 3 1 0 1 0

題目大意:給出一個序列,對該序列中的每一個數,計算它的右邊比他小的數字的個數。

解題思路:本題是1009的改編,我們可以使用樹狀數組和平衡二叉樹

樹狀數組

與1009不同的是,我們需要先對序列進行處理,以24 35 12 1 56 23爲例,改寫成3,4,1,0,5,2,即他們的大小序號,可以利用map會根據value進行排序的特性達到改寫的目的。

在維護樹狀數組的時候可以從右往左進行update。

#include <bits/stdc++.h>
#define lowbit(i) ((i) & (-i))
using namespace std;
const int maxn = 100005;
int c[maxn];
void update(int x, int val){
	for(int i = x; i < maxn; i += lowbit(i))
		c[i] += val;
}
int getSum(int x){
	int ans = 0;
	for(int i = x; i >= 1; i -= lowbit(i))
		ans += c[i];
	return ans;
}
int main(){
	int n, temp, cnt = 0;
	scanf("%d", &n);
	vector<int> a(n);
	map<int, int> m;
	for(int i = 0; i < n; ++ i){
		scanf("%d", &temp);
		m[temp] = i;
	}
	for(auto it = m.begin(); it != m.end(); ++ it)
		a[(*it).second] = ++cnt;
	for(int i = n-1; i >= 0; -- i){
		update(a[i], 1);
		a[i] = getSum(a[i]-1); 
	}
	printf("%d", a[0]);
	for(int i = 1; i < n; ++ i)
		printf(" %d", a[i]);
}

平衡二叉樹

用平衡二叉樹不需要改寫序列,更簡單

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
int main(){
	tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> tr;
	int n;
	scanf("%d", &n);
	vector<int> a(n);
	for(int i = 0; i < n; ++ i)
		scanf("%d", &a[i]);
	for(int i = n-1; i >= 0; -- i){
		tr.insert(a[i]);
		a[i] = tr.order_of_key(a[i]);
	}
	printf("%d", a[0]);
	for(int i = 1; i < n; ++ i)
		printf(" %d", a[i]);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章