본문 바로가기

알고리즘 문제 풀이/Baekjoon

1395 - 스위치

반응형
SMALL

 

 

1395번: 스위치

첫 줄에는 스위치의 개수 N(2 ≤ N ≤ 100,000)과 처리할 일의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 M개의 줄에 대해 각 줄에 처리할 일에 대한 정보가 담겨진 세 개의 정수 O, Si, Ti가 입력된다. O

www.acmicpc.net

 

#include <stdio.h>

typedef long long ll;

const ll LN = 1e5;

ll tree[LN * 3 + 10];
ll lazy[LN * 3 + 10];

ll N, M;

void propagate(ll n, ll s, ll e) {
  if (lazy[n] % 2) {
    tree[n] = (e - s + 1) - tree[n];

    if (s != e) {
      ++lazy[n * 2];
      ++lazy[n * 2 + 1];
    }

    lazy[n] = 0;
  }
}

void update(ll n, ll s, ll e, ll qs, ll qe) {
  propagate(n, s, e);

  if (qe < s || e < qs) { return; }
  if (qs <= s && e <= qe) {
    tree[n] = (e - s + 1) - tree[n];

    if (s != e) {
      ++lazy[n * 2];
      ++lazy[n * 2 + 1];
    }

    return;
  }

  ll m = (s + e) / 2;

  update(n * 2, s, m, qs, qe);
  update(n * 2 + 1, m + 1, e, qs, qe);

  tree[n] = tree[n * 2] + tree[n * 2 + 1];
}

ll query(ll n, ll s, ll e, ll qs, ll qe) {
  propagate(n, s, e);

  if (qe < s || e < qs) { return 0; }
  if (qs <= s && e <= qe) { return tree[n]; }

  ll m = (s + e) / 2;

  return query(n * 2, s, m, qs, qe) + query(n * 2 + 1, m + 1, e, qs, qe);
}

void init() {
  scanf("%lld %lld", &N, &M);
}

void cal() {
  for (ll m = 0; m < M; ++m) {
    ll O, S, T;

    scanf("%lld %lld %lld", &O, &S, &T);

    if (O) {
      printf("%lld\n", query(1, 1, N, S, T));
    } else {
      update(1, 1, N, S, T);
    }
  }
}

int main(void) {
  // freopen("1395.txt", "r", stdin);

  init();

  cal();

  return 0;
}

 

범위 내 스위치 반전을 하는 방법 = 범위 - 현재 켜진 스위치 갯수

 

이것만 기억하면 쉬운 문제

반응형
LIST

'알고리즘 문제 풀이 > Baekjoon' 카테고리의 다른 글

2014 - 소수의 곱  (0) 2023.12.27
3006 - 터보소트  (1) 2023.12.27
1074 - Z  (0) 2023.12.24
19646 - Random Generator  (0) 2023.12.24
1849 - 순열  (0) 2023.12.24