백준 알고리즘 4442번 : 빌보의 생일

Zoo Da·2021년 12월 2일
0

백준 알고리즘

목록 보기
275/337
post-thumbnail

링크

https://www.acmicpc.net/problem/4442

sol1) 세그먼트 트리 + inversion counting

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define int int64_t
using namespace std;

using pii = pair<int, int>;

template<typename T = int64_t, size_t sz = 17, typename F = plus<T>>
struct SegTree {
	vector<T> tree; T t; F f{};
	SegTree(T t = T()) : tree(1 << sz + 1, t), t(t) {}
	explicit SegTree(T t, const F& f) : tree(1 << sz + 1, t), t(t), f(f) {}
	
	void Init() {
    for (int i = (1 << sz) - 1; i; i--) {
      tree[i] = f(tree[i << 1], tree[i << 1 | 1]);
    }
  }

	void Update(int i, T val) {
		--i |= 1 << sz; tree[i] = val;
		while (i >>= 1) tree[i] = f(tree[i << 1], tree[i << 1 | 1]);
	}
	T Query(int l, int r) {
		T L = t, R = t; --l |= 1 << sz, --r |= 1 << sz;
		while (l <= r) {
			if (l & 1) L = f(L, tree[l++]);
			if (~r & 1) R = f(tree[r--], R);
			l >>= 1, r >>= 1;
		}
		return f(L, R);
	}
};

int32_t main() {
  fastio;
  int n;
  while(cin >> n && n != 0){
    int r = 0;
    SegTree<int,20> ST;
    map<string,int> M;
    for(int i = 0; i < n; i++){
      string t; cin >> t;
      M[t] = i + 1;
    }
    for(int i = 0; i < n; i++){
      string s; cin >> s;
      r += (M[s] - 1 - ST.Query(1, M[s]));
      ST.Update(M[s], 1);
    }
    cout << r << "\n"; 
  }
}

sol2) FenwickTree + inversion counting

#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define int int64_t
using namespace std;

using pii = pair<int, int>;

template <size_t sz>
struct FenwickTree
{
  vector<int> tree;
  FenwickTree() : tree(sz + 1) {}
  void update(int i, int val)
  {
      for (; i <= sz; i += i & -i)
          tree[i] += val;
  }
  int query(int i)
  {
      int ret = 0;
      for (; i; i -= i & -i)
          ret += tree[i];
      return ret;
  }
};

int32_t main(){
  int n;
  while(cin >> n && n != 0){
    int r = 0;
    FenwickTree<100001> FT;
    map<string,int> M;
    vector<pii> v(n);
    for(int i = 0; i < n; i++){
      string s; cin >> s;
      M[s] = i + 1;
    }
    for(int i = 0; i < n; i++){
      string s; cin >> s;
      int idx = M[s];
      v[i] = {idx, i + 1};
    }
    sort(v.begin(), v.end());
    for(int i = n - 1; i >= 0; i--){
      int t = v[i].second;
       r += FT.query(t - 1);
       FT.update(t, 1);
    }
    cout << r << "\n";
  }
}

입력이 문자열로 들어오기 때문에 map을 사용해서 판별을 해주어야합니다.
FenwickTree를 사용해서 뒤에서부터 inversion의 값을 판별해주면 됩니다.

profile
메모장 겸 블로그

0개의 댓글