https://nanti.jisuanke.com/t/41400
큰 위해, 우리는 오른쪽으로 가치와 B, A와 C, C와 B의 컨벌루션의 배열을 설정 한 후 응답을 컨볼 루션 불법 상황을 뺀 후, N ^ $ 3 $이고
그러나, 각 시간 범위 $ $ 1E5 및 회선 여섯 번마다 한 세트의 복잡성을 수행 할 수 있기 때문에 $ 6 * 2 ^ {CEIL (로그 (2N))} CEIL (로그 (2N)) N = 1E5은 CEIL (X) $는 반올림
테스트 데이터 (100) 설정된 경우, $ 2.8e9 $에 도달 할 수 있습니다
그러나, 우리는 데이터의 5 분의 1이 $ N> $ 1000을 충족 발견
따라서, 소규모 데이터에 대해, 우리는 직접 $의 N ^ 2 $ 폭력을 사용
#INCLUDE <. 비트 / stdc ++ H> #DEFINE이 줄게 긴 긴 #DEFINE 렙 (II, a가, b)에 대한이 (INT II하면 A =; II <= B; ++ II) 당 #DEFINE (II A, B) 경우 (= INT II의 B]는 II> A = - II) std 네임 스페이스를 사용하여 // 헤드 CONST의 INT maxn = 4e5 + 10 MAXM = 2e6 + (10); INF = CONST LL 0x3f3f3f3f, 개조 1E9 + = 7; INT의 CASN, N, M, K, 카세 = 1, L, R; 스페이스 fastio {// @支持读取整数,字符串,输出整数@ BOOL isdigit에 (문자 c) {C가 복귀> = 48 && C <= 57} CONST의 INT maxsz = 1E7; 클래스 fast_iostream {공개 : 숯불 채널 = get_char (); 부울 ENDF = 1, 플래그; 숯 get_char () { 정적 문자 버퍼 [maxsz] * A = 버퍼 * B = 버퍼; 리턴 B에서 == && (b = (a = 버퍼) + FREAD (완충액 1 maxsz 표준 입력), B == a) EOF : *는 ++; } 서식 <유형 이름 유형> 부울 GET_INT (타입 TMP) { 플래그 = TMP = 0; (! isdigit에 (CH3) CH = && EOF) 동안 { '-'플래그 == = CH, CH = get_char ();}; 경우 (CH2 == EOF) 반환 ENDF = 0; 이렇게 {TMP = CH-48 * 10 + TMP} 동안 (isdigit에 (CH2 = get_char ())); (플래그) TMP = -tmp 경우; 1을 반환; } INT의 get_str (숯 *의 STR) { CHAR * TMP = STR; 동안 (CH2 == '\ R'|| CH == '\ n'|| CH == ') CH = get_char (); 경우 (CH2 == EOF) 창 (ENDF = 0) * TMP = 0; 할 {* (TMP ++) = CH, CH = get_char ();} (CH = '\ 연구'를 ch && = '\ n'을 && CH = ''&& CH = EOF!!!!) 동안; * (TMP는 ++) = 0; 리턴 (INT) (TMP-STR-1); } fast_iostream & 연산자 >> 서식 <유형 이름 유형> fast_iostream & 연산자 >> (타입 TMP) {GET_INT (TMP) *이 반환} {복귀 ENDF} 불리언 연산자 ()을 const }; } fastio :: fast_iostream IO; CONST 이중 PI = ACOS (-1.0); CP 구조체 {이중 X, Y}; CP 연산자 * (CP의 A, 및 CP b) {창 {AX * BX-AY * 의해 AX * b.y + (AY)의 *의 BX}} CP 연산자 + (CP의 A, 및 CP b) {창 {a.x + BX , a.y의 + 의해}} CP의 운용자 (CP의 A, 및 CP b) {창 {AX-BX, AY-의해}} 클래스 푸리에 {공개 : INT 레브 [maxn, LEN, PW; 보이드 INIT (INT 않음) { 렌 = 1, PW = 0; 반면 (LEN <= N) = 1 << LEN, PW ++; 렙 (I 0, 렌-1) 레브 [I] = 0; 렙 (I 0, 렌-1) REV [I] = (REV [I >> 1] >> 1) | ((I & 1) << (PW-1)); } 공극은 {(CP * A, INT 플래그) 변환 경우 담당자 LEN (I-1, 0) (난 레브 <[I]) 스왑 (a [i]를, A [REV [I]); 대 (INT 중간 = 1, 중간 <LEN, 중간 << = 1) { CP WN = {COS (PI / MID), 플래그 * 죄 (PI / MID)}; 대 (INT의 R = 1 << 미드, J = 0; J <LEN, J = R +) { 및 CP t = {1,0}; CIN >> CASN; 대 (INT에서 K = 0; K <미드; ++ K는, t는 t의 *의 WN을 =) { CP X = A [J + K, Y = t * A [중간 +의 J + K]; A [J + K] = X + Y, A [J + K + 중간]를 XY =; } } } 경우 (플래그 == - 1) 담당자 (I 0, LEN)는 [I]를 .x와 / = LEN; } } FFT; , A [maxn], B [maxn]을 int로 [maxn] C; CP CNTA [maxn] CNTB [maxn] CNTC [maxn]; CP의 RESA [maxn]에 resb [maxn] resc [maxn]; LL 스마 [maxn] sumb [maxn] sumc [maxn]; #DEFINE CIN IO INT의 main () { 렙 (I, 1, N) C의 CIN >> [I]; LL ANS = 1ll * N의 N *의 * 않음; (카세 <= CASN) {동안 CIN >> N; fft.init (1E5 + 1E5 + 2); 경우 (N <= 1000) { 렙 (I, 1, N) CIN >> A [I]; 렙 (I, 1, N) CIN >> B [I]; 정렬 (c + 1, C + N + 1); 정렬 (B + 1, B + N + 1); 정렬 (A + 1, A + N + 1); 렙 (I, 1, 3 [N]) 스마 [I] = 0; 렙 (I, 1, N) 렙 (j, 1, N) ++ 스마 [A [I] + B [J]]; 렙 (I, 1, 3 [N]) 스마 [I] + = 스마 [I-1]; 렙 (I, 1, N) = ans- 스마 [C [I] -1] 렙 (I, 1, 2 [N]) 스마 [I] = 0; 렙 (I, 1, N) 렙 (j, 1, N) ++ 스마 [A [I] + C [J]]; 렙 (I, 1, 2 [N]) 스마 [I] + = 스마 [I-1]; 렙 (I, 1, N) = ans- 스마 [B [I] -1] 렙 (I, (1), [N]) 스마 [I] = 0; 렙 (I, 1, N) 렙 (j, 1, N) ++ 스마 [C [I] + B [J]]; 렙 (I, (1), [N]) 스마 [I] + = 스마 [I-1]; 렙 (I, 1, N) = ans- 스마 [A [I] -1] 의 printf ( "케이스 # 1 %의 D % LLD \ 없음"카세 ++, ANS); 계속하다; } (I, 1, N) {수신 CIN >> A [I]; CNTA [A [I] X ++.; } 렙 (I, 1, N) { CIN >> B [I]; CNTB [B [I] X ++.; } 렙 (I, 1, n)이 { (CIN) >> (C)의 [I]; CNTC [C [I] X ++.; } fft.transform (CNTA 1) fft.transform (CNTB, 1); fft.transform (CNTC, 1); 렙 (I 0, fft.len-1) { RESA [I] = CNTB [I] * CNTC [I]; 에 resb [I] = CNTA [I] * CNTC [I]; resc [I] = CNTB [I] * CNTA [I]; } fft.transform (RESA, -1); fft.transform (에 resb, -1); fft.transform (resc, -1); 렙 (I, 1 fft.len-1) { 스마 [I] = 스마 [I-1] + (LL) (RESA [I] .x와는 + 0.5); sumb [I] = sumb [I-1] + (LL) (에 resb [I] .x를 + 0.5); sumc [I] = sumc에 [I-1] + (LL) (resc [I] .x를 + 0.5); } LL ANS = N * 1ll의 * N 개의 * 않음; 렙 (I, 1, N) { 스마 ans- = [A [I] -1] + sumb [B [I] -1] + sumc [C [I] -1] } 의 printf ( "케이스 # % d에 % LLD \ 없음"카세 ++, ANS); 렙 (I 0, fft.len) { CNTA [I] = CNTB [I] = CNTC [I] = (CP) {0,0}; } } }