만행의 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를 가지고 있는지 확인한다.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
사용법 #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 것 같다).
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
사용법 #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); }