[21718][伯俊/BOJ]圧縮18870号座標


質問する



にゅうしゅつりょく



に答える


これは,配列に自分より小さい値がいくつか存在するかを探す問題である.
二重for文を使えばいいのですが、nの値は最大100万なので、O(n^2)では解決できません.したがって,O(nlogn)以下の時間的複雑さを解決しなければならない.

  • 二重ベクトルを宣言し、配列とビット値を加えます.(2,0), (4,1), (-10,2), (4,3), (-9,4)

  • 昇順に並べる.(-10,2), (-9,4), (2,0), (4,1), (4,3)

  • 配列を宣言して、自分より小さい値がいくつか存在するかを検索し、arr[num[0]をクリックします.second]を0にリセットします.arr[num[0].second]はarr[2]と同様に-10未満の値は存在しないため、0に初期化される.

  • 繰り返し文では、(i=1~n)num[i]とnum[i-1]のfirst値は同じであり、同じであればそのまま入れ、同じでなければ古い値+1を入れる.

  • コード#コード#

    #include <bits/stdc++.h>
    using namespace std;
    
    int arr[1000002];
    int main()
    {
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    
    	int n;
    	cin >> n;
    	vector<pair<int, int>> num(n);
    
    	for (int i = 0; i < n; ++i)
    	{
    		cin >> num[i].first;
    		num[i].second = i;
    	}
    
    	sort(num.begin(), num.end());
    	arr[num[0].second] = 0;
    
    	for (int i = 1; i < n; ++i)
    	{
    		if (num[i].first == num[i - 1].first)
    			arr[num[i].second] = arr[num[i - 1].second];
    		else
    			arr[num[i].second] = arr[num[i - 1].second] + 1;
    	}
    	for (int i = 0; i < n; ++i)
    		cout << arr[i] << ' ';
    }