HDU 3974 지정 작업 (세그먼트 트리 DFS 순서)

문제 설명

(N 1부터 번호) N의 직원이 회사, 회사의 모든 직원이 당신이 누군가의 즉각적인 보스 .If, 그 사람이 당신의 종속 (회사 전체의 지도자 제외) 즉시 상사를 가지고가있다, 그의 모든 부하 직원은 부하 직원도 있습니다. 당신은 누구의 보스 인 경우에, 당신은 어떤 부하 직원이없는, 즉각적인 상사가없는 직원은이 N의 직원이 나무를 형성 의미 전체 company.So의 선두 주자입니다.

이 회사는 일반적으로 작업이 누군가에 할당 finish.When 일부 직원들에게 일부 작업을 할당, 그 / 그녀는 모든 그 / 그녀의 subordinates.In 다른 말을하는 사람을 지정하고 모든 그 / 그녀의 부하 직원이에서 작업을 받았습니다 같은 시간. 직원이 작업을 수신 할 때마다 또한, 그 / 그녀는 (그 / 그녀가있는 경우) 현재 작업을 중지하고 새로운 하나를 시작합니다.

일부 직원에게 몇 가지 작업을 할당 회사 후 일부 직원의 현재 작업을 파악에 도움이되는 프로그램을 작성하라.
 

 

입력

첫 번째 라인은 하나의 양의 정수는 T (T <= 10), 테스트 케이스의 수를 나타낸다 포함한다.

각 테스트 케이스의 경우 :

첫 번째 줄은 종업원 수 정수 N (N ≤ 50,000)를 포함한다.

다음 N - 1 개 라인마다 두 정수 V 직원 직원의 즉각적인 보스 수단 U 및 V를 포함 U (1 <= U, V <= N).

다음 줄은 정수 M (M ≤ 50,000)이 포함되어 있습니다.

다음 M 라인 각 중 하나 인 메시지가 포함

직원 x의 현재 작업에 대한 문의 의미 "C의 X"

또는

회사가 직원의 X에 작업 Y를 할당 의미 "T의 x 및 y"를.

(1 <= X의 <= N, 0 <= Y <= 10 ^ 9)
 

 

산출

테스트 케이스를 들어, 출력 라인마다 대응 응답 모든 문의에 대한 그 첫번째 라인 (1부터) 테스트 케이스 번호를 인쇄.
 

 

샘플 입력

1 3 5 4 3 2 1 3 5 2 5 3 C C T 2 1 3 2 3 T C 3
 

 

샘플 출력

사례 # 1 : -1 1 2

아이디어 :

나무에 DFS 순서 문제에 트리 라인의 설립은 매우 근본적인 문제는 새로운 +의 질문의 단일 지점 간격으로 변환됩니다 그의 아들 노드가 우리가 주문 DFS의 지점을 찾을 수있는 몇 가지 문제 사이의 범위

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병;
CONST  이중 PI ACOS = (- 1.0 );
CONST의  INT N = 5e4 + (7) ;
CONST  INT INF = 0x3f3f3f3f ;
CONST   EPS 1e- = 6 ; 
타입 정의  LL;
CONST LL 모드 1E9 + = 7 ;
구조체 에지 {
     int로 다음에, V; 
}; 
에지 E [N << 1 ];
INT의 헤드 [N], CNT, TOT, L [N], 플래그 [N], R [N];
초기화 () { 
    CNT = 0 ; 
    TOT = 0 ; 
    memset 함수 (헤드, 0 , 는 sizeof (헤드)); 
    memset 함수 (플래그 0 , 는 sizeof (플래그)); 
} 
공극 추가 ( INT U, INT V) { 
    E [ ++ CNT = 가장자리 헤드 {[U, V}; 
    헤드 [U] = CNT; 
} 
공극 DFS ( INT U) { 
    L [U]는 = ++ TOT;
    위한 ( int로 , I, I = 헤드 [U] I = E [i]는 다음 내용을) {
         INTV = E [I] .V; 
        DFS (V); 
    } 
    R [U]는 = ++ TOT; 
} 
구조체 나무 {
     INT의 L, R, V, 게으른; 
t} [N << 2 ];
보이드 빌드 ( INT의 P, INT의 L, INT의 R) { 
    t의 [피] 펜닐 = 1; t [P] = R .R; t [P] .V = - 1 ; t [P] .lazy = 0 ;
    경우 (L == R) ;
    int로 중간 = (L + R) >> 1 ; 
    빌드 (p << 1 , L, MID); 
    P (빌드 << 1 |1 , 중간 + 1 , R); 
} 
공극 푸시 ( INT의 P) {
     경우 (t의 [피] .lazy) { 
        t [P << 1 ] .V = t [P] .lazy; 
        t의 [P << 1 | 1 ] .V = t [P] .lazy; 
        t [P << 1 ] .lazy = t [P] .lazy; 
        t의 [P << 1 | 1 ] .lazy = t [P] .lazy; 
        t [P] .lazy = 0 ; 
    } 
} 
공극 업데이트 ( INT의 P, INT의 L, INTR, INT의 V) {
     경우 (L <= t [P] 펜닐 && t [P] .R <= R) { 
        t의 [피] .lazy = V; 
        t [P] .V = V;
        반환 ; 
    } 
    푸시 (p); 
    INT 중간 = (t [P] 펜닐 + t의 [P] .R) >> 1 ;
    경우 (L <= MID) 업데이트 (p << 1 , L, R, V);
    경우 (R> MID) 업데이트 (p << 1 | 1 , L, R, V); 
} 
INT의 쿼리 ( INT의 P, INT의 X) {
     경우 (t의 [피] == .L를 t [P] .R && t [P] 펜닐 == X) {
         반환 t [P] .V;
    } 
    푸시 (p); 
    INT 중간 = (t [P] 펜닐 + t의 [P] .R) >> 1 ;
    INT 고해상도;
    경우 (X <= MID) 입술 = 쿼리 (p << 1 , X);
    다른 고해상도 = 쿼리 (p << 1 | 1 , X);
    반환 입술을; 
} 
INT 주 () { 
    IOS :: sync_with_stdio ( 거짓 ); 
    cin.tie ( 0 ); cout.tie ( 0 );
    INT의 t; CIN >> t;
    INT w = 0 ;
    반면 (t-- ) { 
        COUT << " 케이스 # " << ++ << 승 " : " << ENDL; 
        INIT는 () 
        값 int m, n은, CIN >> N;
         위해 ( int로 I = 1 ; i가 N <; 내가 ++ ) {
             int로 U를 V; CIN >> U를 >> V, 
            추가 (V, U), 
            플래그 [U] = 1 ; 
        } 
        INT (S)]
         에 대해 ( int로 I = 1 ; i가 <= N; 내가 ++ )
             경우 (! 플래그 [I]) { 
                (S) = 난; 중단 ;
            } 
        DFS (S);
        구축 (  11 , 1 , N << 1 ); 
        CIN >> m;
        위한 ( int로 난 = 1 ; I <= m 내가 ++ ) {
              연산하는 단계; CIN >> OP;
            경우 (OP == ' C ' ) {
                 INT (X); CIN >> X; 
                COUT << 쿼리 ( 1 , L은 [X]) << ENDL; 
            } 다른 {
                 INT의 X, Y; CIN >> >> X , Y; 
                업데이트 ( , L [X], R [X, Y);
            } 
        } 
    } 
}
코드보기

 

추천

출처www.cnblogs.com/wmj6/p/11431924.html