BOJ 15648 - 추출하는 폴도 바리스타입니다

image.png

naive하게 $dp$ 식을 세우면

$dp_{i}$는 $1+Max_{j=i+1}^{n-1} \{dp_{j} ~\text{if}~ a_{i}\equiv a_{j}~(mod~k)\}$ 이나

$1+Max_{j=i+1}^{n-1} \{dp_{j} ~\text{if}~ a_{j}-d \le a_{i}\le a_{j}+d \}$ 둘 중에 큰 값이여야 하고 구하는데 $O(n^2)$ 이 걸린다.

따라서 이걸 세그먼트 트리로 최적화하여 $O(n\log n)$에 문제를 해결하도록 한다.

두 세그먼트 트리를 준비하고 $dp$ 값에 대한 지금까지 나온 범위중에 $max$ 값을 찾도록 한다.

void solve() {  
   int n, k, d;  
   cin >> n >> k >> d;  
   vi a(n);  
   fv(a);  
  
   seg_tree<int> dp_sum(6e5), dp_mod(k + 5);  
  
   int ans = 0;  
   for (int i = n - 1; i >= 0; i--) {  
      int mod = a[i] % k;  
      int cur = dp_mod.query(mod, mod).max;  
      cur = max(cur, dp_sum.query(max(1, a[i] - d), min(a[i] + d, int(5e5))).max);  
  
      cur++;  
      ans = max(ans, cur);  
  
      dp_mod.update(mod, cur);  
      dp_sum.update(a[i], cur);  
   }  
   cout << ans;  
}

Tags:

Categories:

Updated:

Comments