세그멘트 트리 레이지 프로퍼게이션 문제.
이것 역시 겨울학교에서 복붙했다 ㅋㅋ
1395번: 스위치
첫 줄에는 스위치의 개수 N(2 ≤ N ≤ 100,000)과 처리할 일의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 M개의 줄에 대해 각 줄에 처리할 일에 대한 정보가 담겨진 세 개의 정수 O, Si, Ti가 입력된다. O
www.acmicpc.net
레이지세그는 갱신을 필요할때만 하게끔 따로 propergate()라는 함수를 작성해주는데,
이것이 구간쿼리를 더 빠르게 처리할 수 있게 해준다.
#include <stdio.h>
#include <algorithm>
#include <vector>
#define MID ((s+e)/2)
using namespace std;
int seg[456789] = {0}; // 구간에서의 켜진 스위치의 수.
int lazy[456789] = {0};
void propagate(int node, int s, int e){
if(!(lazy[node]%2)) return;
if(s!=e){
lazy[node*2] += lazy[node];
lazy[node*2 + 1] += lazy[node];
}
seg[node] = (e-s+1) - seg[node];
lazy[node] = 0;
}
void update(int L, int R, int node, int s, int e){
propagate(node, s, e);
if(R<s || e<L) return;
if(L<=s && e<=R){
if(s!=e){ lazy[node*2]++; lazy[node*2+1]++; }
seg[node] = (e-s+1)-seg[node];
return;
}
update(L,R,node*2, s, MID);
update(L,R,node*2+1, MID+1, e);
seg[node] = seg[node*2] + seg[node*2+1];
}
int query(int L, int R, int node, int s, int e){
propagate(node, s, e);
if(R<s || e<L) return 0;
if(L<=s && e<=R) return seg[node];
int val = 0;
val += query(L,R,node*2, s, MID);
val += query(L,R,node*2+1,MID+1, e);
return val;
}
int main(){
int n,m;
int a,b,c;
scanf("%d %d", &n, &m);
while(m--){
scanf("%d %d %d", &a, &b, &c);
if(a==0) update(b,c,1,1,n);
if(a==1) printf("%d\n", query(b,c,1,1,n));
}
return 0;
}
깔끔하게 AC.
반응형