結果

問題 No.2988 Min-Plus Convolution Query
ユーザー ygussanyygussany
提出日時 2024-12-17 12:12:39
言語 C
(gcc 12.3.0)
結果
AC  
実行時間 1,446 ms / 2,000 ms
コード長 7,313 bytes
コンパイル時間 725 ms
コンパイル使用メモリ 36,384 KB
実行使用メモリ 11,652 KB
最終ジャッジ日時 2024-12-17 12:13:08
合計ジャッジ時間 28,884 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
10,096 KB
testcase_01 AC 3 ms
9,972 KB
testcase_02 AC 1,422 ms
10,900 KB
testcase_03 AC 1,438 ms
11,208 KB
testcase_04 AC 1,427 ms
11,024 KB
testcase_05 AC 31 ms
10,096 KB
testcase_06 AC 3 ms
8,064 KB
testcase_07 AC 3 ms
10,096 KB
testcase_08 AC 3 ms
10,092 KB
testcase_09 AC 46 ms
10,100 KB
testcase_10 AC 33 ms
9,996 KB
testcase_11 AC 8 ms
10,100 KB
testcase_12 AC 12 ms
8,208 KB
testcase_13 AC 197 ms
10,112 KB
testcase_14 AC 15 ms
10,104 KB
testcase_15 AC 273 ms
10,120 KB
testcase_16 AC 1,167 ms
10,764 KB
testcase_17 AC 121 ms
11,460 KB
testcase_18 AC 116 ms
11,652 KB
testcase_19 AC 90 ms
10,356 KB
testcase_20 AC 1,403 ms
11,284 KB
testcase_21 AC 1,446 ms
11,288 KB
testcase_22 AC 1,442 ms
11,024 KB
testcase_23 AC 1,402 ms
11,144 KB
testcase_24 AC 1,400 ms
11,156 KB
testcase_25 AC 1,419 ms
11,368 KB
testcase_26 AC 1,393 ms
11,120 KB
testcase_27 AC 1,417 ms
11,252 KB
testcase_28 AC 1,370 ms
11,024 KB
testcase_29 AC 1,438 ms
10,748 KB
testcase_30 AC 1,422 ms
11,244 KB
testcase_31 AC 1,402 ms
10,896 KB
testcase_32 AC 3 ms
9,972 KB
testcase_33 AC 3 ms
10,104 KB
testcase_34 AC 3 ms
10,100 KB
testcase_35 AC 3 ms
10,100 KB
testcase_36 AC 3 ms
10,104 KB
testcase_37 AC 3 ms
10,096 KB
testcase_38 AC 3 ms
9,972 KB
testcase_39 AC 3 ms
10,100 KB
testcase_40 AC 2 ms
10,100 KB
testcase_41 AC 2 ms
9,980 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <stdio.h>

const int sup = 2000000001;

void chmin(int *a, int b)
{
	if (*a > b) *a = b;
}

void chmax(int *a, int b)
{
	if (*a < b) *a = b;
}

void merge_sort(int n, int x[])
{
	static int y[200001] = {};
	if (n <= 1) return;
	merge_sort(n / 2, &(x[0]));
	merge_sort((n + 1) / 2, &(x[n/2]));
	
	int i, p, q;
	for (i = 0, p = 0, q = n / 2; i < n; i++) {
		if (p >= n / 2) y[i] = x[q++];
		else if (q >= n) y[i] = x[p++];
		else y[i] = (x[p] < x[q])? x[p++]: x[q++];
	}
	for (i = 0; i < n; i++) x[i] = y[i];
}

void min_plus_convolution3(int A[], int B[], int q[], int l1, int r1, int l2, int r2, int l3, int r3, int end_argmin[])
{
	/*
	fprintf(stderr, "[%d %d %d %d %d %d]\n", l1, r1, l2, r2, l3, r3);
	for (int i = l1 - 1; i <= r1; i++) fprintf(stderr, "%d ", end_argmin[q[i]]);
	fprintf(stderr, "\n");
	*/
	
	if (l3 > r3) return;
	if (q[l1] + l2 > r3) {
		chmin(&(end_argmin[q[l1-1]]), l3);
		return;
	}
	if (q[r1] + r2 < l3) {
		chmin(&(end_argmin[q[r1-1]]), r3);
		return;
	}
	if (l1 == r1) {
		chmin(&(end_argmin[q[l1-1]]), l3);
		return;
	}
	chmax(&l2, l3 - q[r1]);
	chmin(&r2, r3 - q[l1]);
	
	int i, j, k = (l3 + r3) / 2, min, argmin;
	for (i = l1, min = sup; i <= r1; i++) {
		j = k - q[i];
		if (j > r2) continue;
		else if (j < l2) break;
		if (min > A[q[i]] + B[j]) {
			min = A[q[i]] + B[j];
			argmin = i;
		}
	}
	if (min == sup) {
		if (q[l1] + l2 <= r3) argmin = l1;
		else argmin = r1;
	}
	chmin(&(end_argmin[q[argmin-1]]), k);
	min_plus_convolution3(A, B, q, l1, argmin, l2, r2, l3, k - 1, end_argmin);
	min_plus_convolution3(A, B, q, argmin, r1, l2, r2, k + 1, r3, end_argmin);
}

#define THR 60

void solve3(int N, int A[], int B[], int Q, int p[], int x[], int k[], int ans[])
{
	int i, j, bl, br, ql, qr, tail[2][2], l, r, m, min, max;
	static int q[2][2][200001], appear[200001], end_argmin[200001];
	for (i = 1; i <= N; i++) appear[i] = 0;
	for (bl = 1; bl <= Q; bl = br + 1) {
		for (br = bl, tail[0][1] = 0, q[0][1][0] = 0, min = N * 2, max = 2; br <= Q && br < bl + THR * THR; br++) {
			if (appear[p[br]] == 0) {
				appear[p[br]] = 1;
				q[0][1][++tail[0][1]] = p[br];
			}
			chmin(&min, k[br]);
			chmax(&max, k[br]);
		}
		br--;
		merge_sort(tail[0][1], &(q[0][1][1]));

		for (i = 1, tail[0][0] = 0, q[0][0][0] = 0; i <= N; i++) if (appear[i] == 0) q[0][0][++tail[0][0]] = i;
		for (i = 1, end_argmin[0] = 2; i <= tail[0][0]; i++) end_argmin[q[0][0][i]] = N * 2 + 1;
		min_plus_convolution3(A, B, q[0][0], 1, tail[0][0], 1, N, 2, N * 2, end_argmin);
		for (i = tail[0][0] - 1; i >= 1; i--) chmin(&(end_argmin[q[0][0][i]]), end_argmin[q[0][0][i+1]]);
		for (i = bl; i <= br; i++) appear[p[i]] = 0;
		/*
		for (i = 0; i <= tail[0][0]; i++) printf("(%d %d) ", q[0][0][i], end_argmin[q[0][0][i]]);
		printf("\n");
		*/
		for (ql = bl; ql <= br; ql = qr + 1) {
			for (qr = ql, tail[1][1] = 0, q[1][1][0] = 0, min = N * 2, max = 2; qr <= br && qr < ql + THR; qr++) {
				if (appear[p[qr]] == 0) {
					appear[p[qr]] = 1;
					q[1][1][++tail[1][1]] = p[qr];
				}
				chmin(&min, k[qr]);
				chmax(&max, k[qr]);
			}
			qr--;
			merge_sort(tail[1][1], &(q[1][1][1]));
			
			for (i = 1, tail[1][0] = 0, q[1][0][0] = 0; i <= tail[0][1]; i++) if (appear[q[0][1][i]] == 0) q[1][0][++tail[1][0]] = q[0][1][i];
			for (i = 1, end_argmin[0] = 2; i <= tail[1][0]; i++) end_argmin[q[1][0][i]] = N * 2 + 1;
			min_plus_convolution3(A, B, q[1][0], 1, tail[1][0], 1, N, 2, N * 2, end_argmin);
			for (i = tail[1][0] - 1; i >= 1; i--) chmin(&(end_argmin[q[1][0][i]]), end_argmin[q[1][0][i+1]]);
			for (i = ql; i <= qr; i++) appear[p[i]] = 0;
			/*
			printf("- ");
			for (i = 0; i <= tail[1][0]; i++) printf("(%d %d) ", q[1][0][i], end_argmin[q[1][0][i]]);
			printf("\n");
			*/
			for (j = ql; j <= qr; j++) {
				A[p[j]] = x[j];
				// for (i = 1, end_argmin[0] = 2; i <= tail[1][1]; i++) end_argmin[q[1][1][i]] = N * 2 + 1;
				// min_plus_convolution3(A, B, q[1][1], 1, tail[1][1], 1, N, 2, N * 2, end_argmin);
				// for (i = tail[1][1] - 1; i >= 1; i--) chmin(&(end_argmin[q[1][1][i]]), end_argmin[q[1][1][i+1]]);
				/*
				printf("-- ");
				for (i = 0; i <= tail[1][1]; i++) printf("(%d %d) ", q[1][1][i], end_argmin[q[1][1][i]]);
				printf("\n");
				*/
				ans[j] = sup;
				if (tail[0][0] > 0) {
					l = 1;
					r = tail[0][0];
					while (l < r) {
						m = (l + r) / 2;
						if (end_argmin[q[0][0][m]] <= k[j]) l = m + 1;
						else r = m;
					}
					if (1 <= k[j] - q[0][0][l] && k[j] - q[0][0][l] <= N) chmin(&(ans[j]), A[q[0][0][l]] + B[k[j] - q[0][0][l]]);
				}
				
				if (tail[1][0] > 0) {
					l = 1;
					r = tail[1][0];
					while (l < r) {
						m = (l + r) / 2;
						if (end_argmin[q[1][0][m]] <= k[j]) l = m + 1;
						else r = m;
					}
					if (1 <= k[j] - q[1][0][l] && k[j] - q[1][0][l] <= N) chmin(&(ans[j]), A[q[1][0][l]] + B[k[j] - q[1][0][l]]);
				}
				
				for (i = 1; i <= tail[1][1]; i++) if (1 <= k[j] - q[1][1][i] && k[j] - q[1][1][i] <= N) chmin(&(ans[j]), A[q[1][1][i]] + B[k[j] - q[1][1][i]]);
				/*
				if (tail[1][1] > 0) {
					l = 1;
					r = tail[1][1];
					while (l < r) {
						m = (l + r) / 2;
						if (end_argmin[q[1][1][m]] <= k[j]) l = m + 1;
						else r = m;
					}
					if (1 <= k[j] - q[1][1][l] && k[j] - q[1][1][l] <= N) chmin(&(ans[j]), A[q[1][1][l]] + B[k[j] - q[1][1][l]]);
				}
				*/
			}
		}
	}
}

#define MT_N 624
#define MT_M 397
#define MT_MATRIX_A 0x9908b0dfUL
#define MT_UPPER_MASK 0x80000000UL
#define MT_LOWER_MASK 0x7fffffffUL

static unsigned int mt[MT_N];
static int mti = MT_N + 1;

void init_genrand(unsigned int s)
{
    mt[0] = s & 0xffffffffUL;
    for (mti = 1; mti < MT_N; mti++) {
        mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
        mt[mti] &= 0xffffffffUL;
    }
}

unsigned int genrand()
{
    unsigned int y;
    static unsigned int mag01[2] = {0x0UL, MT_MATRIX_A};

    if (mti >= MT_N) {
        int kk;
        if (mti == MT_N + 1) init_genrand(5489UL);
		
        for (kk = 0; kk < MT_N - MT_M; kk++) {
            y = (mt[kk] & MT_UPPER_MASK) | (mt[kk+1] & MT_LOWER_MASK);
            mt[kk] = mt[kk+MT_M] ^ (y >> 1) ^ mag01[y&0x1UL];
        }
        for (; kk < MT_N - 1; kk++) {
            y = (mt[kk] & MT_UPPER_MASK) | (mt[kk+1] & MT_LOWER_MASK);
            mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y&0x1UL];
        }
        y = (mt[MT_N-1] & MT_UPPER_MASK) | (mt[0] & MT_LOWER_MASK);
        mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y&0x1UL];

        mti = 0;
    }
  
    y = mt[mti++];

    y ^= (y >> 11);
    y ^= (y << 7) & 0x9d2c5680UL;
    y ^= (y << 15) & 0xefc60000UL;
    y ^= (y >> 18);

    return y;
}

int main()
{
	int i, N, Q;
	static int A[200001], B[200001], p[200001], x[200001], k[200001], ans[200001];
	scanf("%d %d", &N, &Q);
	for (i = 1; i <= N; i++) scanf("%d", &(A[i]));
	for (i = 1; i <= N; i++) scanf("%d", &(B[i]));
	for (i = 1; i <= Q; i++) scanf("%d %d %d", &(p[i]), &(x[i]), &(k[i]));
	solve3(N, A, B, Q, p, x, k, ans);
	for (i = 1; i <= Q; i++) printf("%d\n", ans[i]);
	/*
	for (i = 1; i <= N; i++) A[i] = genrand() % 10;
	for (i = 1; i <= N; i++) B[i] = 0;
	for (i = 1; i <= Q; i++) {
		p[i] = genrand() % N + 1;
		x[i] = genrand() % 10;
		k[i] = genrand() % (N * 2 - 1) + 2;
	}
	solve3(N, A, B, Q, p, x, k, ans);
	for (i = 1; i <= Q; i++) printf("%d\n", ans[i]);
	*/
	fflush(stdout);
	return 0;
}
0