바이올렛 6 컵 지방 선거 시뮬레이션 게임 민들레

https://www.luogu.com.cn/problem/P4168

이름

$ $ A n의 숫자 및 보조 심문 $ m $, Q $ a_l, A_ {1 + 1} \ 도트 모드 A_R $ 무엇을

$ 1 \ leqslant n \ leqslant 40000, 1 \ leqslant m \ leqslant 50000, 1 \ leqslant A_I \ leqslant10 ^ 9 $

문제 해결

처음 블록

방법 1

통계 n이없는, 매우 크기 때문에 이후에 그렇게 할 수있는 개별 데이터의 수

그래서 당신은 직접 큰를 셀 수 있습니다. 이러한 복잡성은 확실히 $ \ mathcal {O} (m \ N 회) $, 타임 아웃 인

당신은 블록으로 분할 $ t의 $로, 사전에 어떤 블록 테이블을 재생하려고하고 최대 $ \하기 Binom {t} {2} 사전에 $ 블록을 배치하고, 이는 저장되어 있습니다

때마다 그래서 쿼리는 $ 2 \ 번 \ lfloor N / t \ ​​rfloor $ 시간이, 시간 복잡도는 $ \입니다 mathcal {O} (t ^ 2N + 200 / t) $까지 지출

$ m $ 및 $ N- $ 동일한 순서로 간주 N에 상기 수득 $ t ^ 2N + 2N ^ 2 / t $, 동일한 정도의 크기를 보장하기 위해, 세트 $의 t는 2N = 2N ^ 2 / t $을 얻었다 ^ t = $ \ SQRT [3] {N} $

((A + B를) $을 증명 $ 최대 (a, b) = \ 세타 알고리즘 소개) 점차 크게 또는 복잡성 후보다 작은 양쪽이 증가하기 때문에, 전체 표현식의 복잡성 점진적 상승을 초래

AC 코드

#INCLUDE <cstdio> 
#INCLUDE <CString을> 
#INCLUDE <알고리즘> 
#INCLUDE <cmath> 
#INCLUDE <큐> 
#INCLUDE <벡터> 
네임 스페이스를 사용하여 표준; 
위한 #DEFINE REP (I, A, B) (등록 I = INT (a) I <(b); I ++) 
#DEFINE REPE (I, A, B)에 대한 (등록 I = INT (a) I < = (b); I ++) 
#DEFINE 페르 (I, A, B)에 대한 (등록 I = INT (a) I> = (B), 난 -) 
#ifdef와 sahdsg 
#DEFINE DBG (...)의 printf (__VA_ARGS__) 
#else 
#DEFINE DBG (...) 보이드 (0) 
#endif 다음 
의 typedef 긴 긴 LL; 
#DEFINE MAXN 40,007 
#DEFINE MAXM 50007 
#DEFINE MAXD 35 
INT A [MAXN], B [MAXN], C [MAXN]; 
INT D [MAXD] MAXD] MAXN]; 
현재 값 int [MAXN]; 
INT t, L, NA;
INT (X) = 0; 
보이드는 인라인 (INT의 F) {한 
	지금 [F]를 ++; 
	경우 (현재 [NA] <지금 [F] || (현재 [NA] == 이제 [F] && 이제 [1 + NA]> F)) { 
		지금 [1 + NA = F; 
		이제 [NA가 이제 = [F] 
	} 
} 
인라인 INT (INT z의 INT Y) 이동 { 
	INT I = (Z + L-1) / l, J = Y / l; 
	INT L = I *은 L, R = J * L; 
	경우 (I <J) { 
		REP (K, 0, NA + 2) 
			이제 [K] = D [I] [J] [K]; 
		REP (F, Z, L) 않았다 (C [F]); 
		REP (F, R, Y)의 한 (C [F]); 
	} 다른 { 
		memset 함수 (현재 0, sizeof 연산자 지금); 
		REP (F, Z, Y)의 한 (C [F]); 
	} 
	리턴 X = B [지금 [1 + NA]; 
} 
() {int로 메인 
	INT를 N, m; scanf와 ( "% D % D", 및 N, m); 
	REP (I, 0, N)는 scanf {( "%의 D ', A [I]); B [I]은 [I]은}
	정렬 (B, B + N); NA = 고유 (B, B + N) -b; 
	REP (I, 0, n)이 {
		C [I] = LOWER_BOUND (B, B +, NA A [I]) - B; 
	} 
	memset 함수 (d, 0는 sizeof d); 
	t = POW ((더블) N, (이중) 1/3); 
	L = t? N / t : N; 
	REP (I, 0, t) REPE (j, I, t) { 
		REP (F, I는 L *, J * l) { 
			INT의 K = C [F]; // DBG ( "* % D \ n" 케이); 
			D [I] [J] [K] ++; 
			경우 (d [I] [J] [K]> D [I] [J] || (d [I] [J] [K] == D [NA] [I] [J] [NA] && K <D [I] [J] [1 + NA])) { 
				D [I] [J] [NA = D [I] [J] [K]; 
				D [I] [J] [1 + NA = K; 
			} 
		} 
	} 

	REP (I 0, m) { 
		INT의 L0, R0; 
		scanf와 ( "% D % D", L0, R0); 
		L = INT (L0 + X - 1) + 1 %, N; 
		INT R = (R0 + X - 1) + 1 %, N; 
		(L> R) - 스왑 (L, R)의 경우; 
		(L-1, R)으로 이동;
		의 printf ( "가 % d \ n", X); 
}

추천

출처www.cnblogs.com/sahdsg/p/12057124.html