Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

dh-winternagi 님의 블로그

(15899) 트리와 색깔 본문

백준 (C++)/Solve

(15899) 트리와 색깔

dh-winternagi 2026. 4. 27. 23:35

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

단계별로 풀어보기

52단계(세그먼트 트리 2) 10번째

 

 

 

오일러 경로 테크닉과 머지 소트 트리를 결합하는 문제. 오일러 경로 테크닉에서 세그먼트 트리의 초기 단일 값은 트리에서 초기 정점 인덱스가 아닌 전위 순회로 방문한 순서라는 새로운 인덱스로 설정해야 한다는 것만 유의하면 된다.

 

 

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define ALL(v) (v).begin(), (v).end()
#define p 1000000007

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  
  int n, m, c, cnt= 0, ans= 0;
  
  cin >> n >> m >> c;
  
  vector<int> v0(n+1), v(n+1), in(n+1), out(n+1);
  vector<vector<int>> adj(n+1);
  
  for(int i=1;i<=n;i++)  cin >> v0[i];
  
  for(int i=1;i<n;i++){
    int a, b;
    
    cin >> a >> b;
    
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  
  auto dfs= [&](auto self, int now, int prev) -> void {
    in[now]= ++cnt;
    v[cnt]= v0[now];
    
    for(int next:adj[now]){
      if(next==prev)  continue;
      
      self(self, next, now);
    }
    
    out[now]= cnt;
  };
  
  cnt= 0;
  dfs(dfs, 1, 0);
  
  int treesize= (1<<(((int)ceil(log2(n+1)))+1));
  vector mstree(treesize, vector<int> ());
  
  auto init= [&](auto self, int s, int e, int node) -> void {
    if(s==e){
      mstree[node].push_back(v[s]);
    }else{
      self(self, s, s+(e-s)/2, node*2);
      self(self, s+(e-s)/2+1, e, node*2+1);
      
      mstree[node].resize(mstree[node*2].size()+mstree[node*2+1].size());
      merge(ALL(mstree[node*2]), ALL(mstree[node*2+1]), mstree[node].begin());
    }
  };
  
  auto query= [&](auto self, int s, int e, int node, int l, int r, int k) -> int {
    if(r<s||e<l)  return 0;
    
    if(l<=s&&e<=r){
      return  upper_bound(ALL(mstree[node]), k)-mstree[node].begin();
    }else{
      long lsum= self(self, s, s+(e-s)/2, node*2, l, r, k);
      long rsum= self(self, s+(e-s)/2+1, e, node*2+1, l, r, k);
      return lsum+rsum;
    }
  };
  
  init(init, 1, n, 1);
  
  while(m--){
    int vi, ci;
    
    cin >> vi >> ci;
    
    ans= (ans+query(query, 1, n, 1, in[vi], out[vi], ci))%p;
  }
  
  cout << ans;
  
  return 0;
}

'백준 (C++) > Solve' 카테고리의 다른 글

(11376) 열혈강호 2  (0) 2026.04.28
(11375) 열혈강호  (0) 2026.04.28
(13544) 수열과 쿼리 3  (0) 2026.04.27
(18437) 회사 문화 5  (0) 2026.04.27
(16357) Circuits  (0) 2026.04.27