8.9 NOIP 시뮬레이션 테스트 (15) 도시 (도시) + 폭탄 (폭탄) + 가위 바위 (RPS)

만행의 T3의 정도를 감안할 때, 내가 먼저 문제에 퇴폐적 인 조각 솔루션을하기로 결정했다.

T1 도시 (도시)

포함 및 배제 방법 배플 +

N 그룹으로 m 건설 팀, 각 그룹이 있어야 상한, C의 합계 (m-1, N-1) 프로그램의 종류를 고려하지 않는다.

K 이상의 I 번째 그룹 오프 발수 용량 C (N, I) * C (미시간 * K-1, N-1) × (I)가 건설 팀 나머지 MI에 대응 케이 * N 그룹 및 팀으로 (k)의 구성은 각각의 그룹은 적어도 하나와 결합 전혀 고려하고 적어도 두 개의 그룹이 N 개의 패킷으로이 I-K가 K보다 큰 I를 가지고 있는지 확인한다.

사용법 #include <iostream> 
#INCLUDE <CString을> 
#INCLUDE <cstdio>
 #DEFINE 개조 998,244,353
 #DEFINE LL 긴 긴
 사용  스페이스 성병; 
LL의 N, M, K, FAC [ 10001000 ], INV의 [ 10001000 ] facinv [ 10001000 ], ANS; 
LL의 C (LL의 X, Y의 LL) 
{ 
    경우 (Y> X) 복귀  0 ;
    반환 FAC를 [X] * facinv [Y] * %의 개조 facinv [XY] %의 모드; 
} 
INT 의 main () 
{ 
    는 scanf ( " %의 LLD %의 LLD의 %의 LLD " , 및 N, M, K);
    경우 (N>m) { 
        둔다 ( " 0 " );
        반환  0 ; 
    } 
    FAC가 [ 0 ] = 1 ; facinv [ 0 ] = 1 ; INV [ 1 ] = 1 ;
    위한 ( int로 I = 1 ; i가 = 최대 (N, M) <; 내가 ++를 ) {
         경우 (I! = 1 ) INV [I] = (MOD-개조 / I) * INV [개조 % I] % 개조; 
        FAC [I] = FAC [I- 1 ] * % 나 개조; 
        facinv [I] = facinv [I- 1 ] * INV [I] % 개조; 
    } 
    에 대한( int로 I = 1 ; i가 N = <; 내가 ++ ) {
         경우 (I & 1 ) ANS = (ANS + C (N, I) * C (MI * K- 1 , N- 1 )) % 개조;
        다른 ANS = (ANS-C (N, I) * C (MI * K- 1 , N- 1 ) + 모드) % 개조; 
    } 
    의 printf ( " % LLD \ 없음 " (C (M- 1 , N- 1 ) -ans는 + 모드) %의 개조);
    반환  0 ; 
}
시티

 

T2 폭탄 (폭탄)

시험 틀린 질문을 많이하지만 난 그것을 잘못하지 않았다 (낭비)

한 경로가 도달 할 수있는 운동이 존재하는 한, 우리는 tarjan 가장 긴 체인을 찾기 위해, 새로운 지점을 구축, 축소 완료도 후 수축 포인트, 각 지점의 깊이는 몇 점 함께 덩어리 (부모 노드 포인트 + 깊이 크기 여야합니다 ), topu 요청 긴 체인 또는 DFS (DFS하지만 쉽게 T 것 같다).

사용법 #include <iostream> 
#INCLUDE <cstdio> 
#INCLUDE <큐>
 사용  스페이스 성병;
구조체 노드 
{ 
    INT , NXT하는 단계; 
} 시간 [ 4001000 ] HH [ 4001000 ];
INT의 N, m, NXT [ 4001000 ], TOT, TET, CNT, DFN [ 1001000 ] 저 [ 1001000 ], S [ 1001000 ];
INT의 상단 NUM, whos는 [ 1001000 ], SZ [ 1,001,000을 , 뒤 [ 1,001,000을 , DEP [ 1001000 ], ANS, NX [ 4001000 ];
BOOL이  있다 [ 1,001,000];
INT의 최대 ( INT의 X, INT의 Y)는 
{ 
    반환 x> y로? X : Y; 
} 
보이드 추가 ( INT의 X, INT의 Y) 
{ 
    H [ ++ TOT] .TO = Y; 
    시간 [더하다] .nxt = NXT [X]; 
    NXT는 [X] = TOT 단계; 
} 
보이드 생성물 ( INT의 X, INT의 Y) 
{ 
    HH [ ++ TET] .TO = Y; 
    HH [TET] .nxt = NX [X]; 
    NX는 [X] = TET 단계; 
} 
무효 tarjan ( INTX) 
{ 
    [X]를 DFN 로우 [X] = ++ = CNT 단계; 
    S의 [ ++ 가기] = X를;  [X] = 1 ;
    위한 ( int로 I = NXT [X]를 I]의 I = H [i]를 .nxt) {
         INT Y =의 H [i]를 .TO;
        만약 (! DFN [Y]) { 
            tarjan (Y); 
            낮은 [X] = 분 (저 [X], 로우 [Y]); 
        } 
        다른  경우 (  [Y]) 로우 [X] = 분 (저 [X] DFN [Y]); 
    }     
    경우 (DFN [X] == 낮은 [X]) { 
        NUM ++ ;
        동안 (1 ) {
             INT TMP = S [top-- ];
             [TMP] = 0 ; 
            whos는 [TMP] = NUM; 
            SZ [NUM] ++ ;
            경우 (X == TMP) 체류 ; 
        } 
    } 
} 
공극 topu () 
{  < INT > Q;
    위한 ( int로 난 = 1 ; I <= NUM 난 ++ )
         경우 (뒤 [I] == 0 ) q.push (I), DEP [I] = SZ [I], ANS = 최대 (ANS, DEP [I을 ]);
    동안(q.size ()) {
         INT (X) = q.front (); q.pop ();
        위한 ( int로 난 NX = [X]를 I, I = 된 HH [I] .nxt) {
             INT Y = 된 HH [I] .TO; 
            뒤 [Y] - ; 
            DEP [Y] = 최대 (DEP [Y], DEP [X] + SZ [Y]); 
            ANS = 최대 (ANS, DEP [Y]);
            만약 (! q.push (Y) 뒤 [Y]); 
        } 
    } 
} 
INT 의 main () 
{ 
    는 scanf ( " %의 D % d에 " , N, m);
    int로 U를 V;
    대한 ( INTI = 1 ; I <= m; 내가 ++ ) { 
        는 scanf ( " % d 개 %의 D ' , U, V); 
        (U를 V)을 추가; 
    } 
    에 대해 ( int로 I = 1 난 ++; i가 N = < )
         경우 (! tarjan (I) DFN [I]);
    위한 ( int로 I = 1 ; i가 = N <; 내가 ++ ) {
          ( INT J = NXT [I] J, j 개의 =의 H [J] .nxt) {
             INT Y =의 H [J] .TO;
            경우 (whos는 [I] =! whos는 [Y]) { 
                광고 (whos는 [I]를 whos [Y]); 
                뒤 [whos는 [Y]++ ; 
            } 
        } 
    } 
    topu (); 
    의 printf ( " % D \ 없음 " , ANS); 
}
폭탄

 

추천

출처www.cnblogs.com/jrf123/p/11328044.html