이탈리아 그건 : 길이 L에 나무, T 색상은 O 작업을 제공하기 위해, 각각의 시간 간격은 일부 염료, 또는 쿼리 유형 컬러 섹션으로 선택 될 수 있습니다
생각 : 라인 세그먼트 리프 노드로 표시되는 디지털 컬러 기록 부모 노드 -1 자식 노드가 두 개의 서로 다른 색> 전체 개수의 부호 자식 노드 0이 색에 대응 한 것을 나타낸다.
사용법 #include <iostream>
#INCLUDE <cstdio>
#INCLUDE <알고리즘>
#INCLUDE <CString을>
#INCLUDE <cmath>
사용 스페이스 성병;
CONST의 INT maxn 1E5 + = 10 ;
INT A [maxn];
INT의 L, t, O;
int로 힘을 [ 35 ];
구조체 노트
{
int입니다 왼쪽, 오른쪽, 합, 게으른;
무효화 (최대 INT 브로)
{
합계 = 브로 단계;
게으른 = 발;
}
} 트리 [maxn *4 ];
보이드 팔 굽혀 펴기 ( INT의 ID)
{
경우 (트리 [ID << 1 ] .sum == - 1 개 || 트리 [ID << 1 | 1 ] .sum == - 1 )
트리 [ID] .sum = - 1 ;
다른 경우 (트리 [ID << 1 ] == .sum 트리 [ID << 1 | 1 ] .sum)
트리 [ID] .sum = 트리 [ID << 1 ] .sum;
다른
나무 [ID] .sum = - 1 ;
}
공극 푸시 ( INT의 ID)
{
경우 (트리 [ID] .lazy)
{
트리 [ID << 1 ] .up (트리 [ID] .lazy);
트리 [ID << 1 | 1 ] .up (트리 [ID] .lazy);
트리 [ID] .lazy = 0 ;
}
}
공극 빌드 ( INT의 ID, INT의 L, INT의 R)
{
트리 [ID] .left = L 단계;
트리 [ID] 됐지 = R;
경우 (L == R)
트리 [ID] .sum = 1 ;
다른
{
INT중간 = (L +에서의 R) / 2 ;
빌드 (ID << 1 , L, MID);
구축 (ID << 1 | 1 , 중반 + 1 , R);
팔 굽혀 펴기 (ID);
}
}
공극 쿼리 ( INT의 ID, INT의 L, INT의 r)을
{
경우 (트리 [ID] .sum =! - 1 )
{
힘 [트리 [ID] .sum] = 1 ;
반환 ;
}
// 푸시 (ID);
INT 중간 = / (트리 [이드] + 트리 [ID] 됐지 .left) 2 ;
경우 (L <= MID) 조회 (ID << 1 , L, R);
만약 (ID << (R> MID) 질의 1 | 1 ], L, R)
}
공극 업데이트 ( INT의 ID, INT의 L, INT R, INT 브로)
{
경우 (L <= 트리 [ID]가 .left && 트리 [ID] 됐지 <= R)
{
트리 [ID] .up (발);
반환 ;
}
푸시 (ID);
INT 중간 = / (트리 [이드] + 트리 [ID] 됐지 .left) 2 ;
경우 (L <= MID) 업데이트 (ID << 1 , L, R, 발);
경우 (R> MID) 업데이트 (ID << 1| 1 , L, R, 발);
팔 굽혀 펴기 (ID);
}
INT 의 main ()
{
는 scanf ( " % D % D % D ' , L, t, O);
구축 ( 1 , 1 , l);
위한 ( int로 I = 1 ; i가 <= O 내가 ++ )
{
숯 연산하는 단계;
getchar가 ();
scanf와 ( " %의 C " , OP);
경우 (OP == ' C ' )
{
INT의 L, R, 색상;
는 scanf ( "% D % D % D ' , L, R, 및 색),
업데이트 ( 1 , L, R, 컬러)
}
다른
{
INT의 L, R,
는 scanf ( " % d 개 %의 D ' , L, R);
memset 함수 (힘, 0 , 는 sizeof (힘))
질의 ( 1 , L, R)
INT ANS = 0 ;
위해 ( int로 I = 1 ; i가 = < 30 ; i가 ++ )
{
경우 VIS ([I])
ANS++ ;
}
의 printf ( " % D \ 없음 " , ANS);
}
}
}