Submission #71280460


Source Code Expand

Copy
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#define KI_MAX (1 << 18) /* 262144 */
struct data_s {
int zero_cnt, one_cnt;
int64_t tentosu, gyaku_tentosu;
};
struct data_s inv(struct data_s d) {
return (struct data_s){
d.one_cnt,
d.zero_cnt,
d.gyaku_tentosu,
d.tentosu
};
}
struct data_s merge(struct data_s l, struct data_s r) {
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#define KI_MAX (1 << 18) /* 262144 */

struct data_s {
	int zero_cnt, one_cnt;
	int64_t tentosu, gyaku_tentosu;
};

struct data_s inv(struct data_s d) {
	return (struct data_s){
		d.one_cnt,
		d.zero_cnt,
		d.gyaku_tentosu,
		d.tentosu
	};
}

struct data_s merge(struct data_s l, struct data_s r) {
	return (struct data_s){
		l.zero_cnt + r.zero_cnt,
		l.one_cnt + r.one_cnt,
		l.tentosu + r.tentosu + (int64_t)l.one_cnt * r.zero_cnt,
		l.gyaku_tentosu + r.gyaku_tentosu + (int64_t)l.zero_cnt * r.one_cnt
	};
}

struct data_s ki[KI_MAX * 2 - 1];
char ki_all_inv[KI_MAX * 2 - 1];

void ki_init(void) {
	int i;
	for (i = 0; i < KI_MAX; i++) {
		ki[KI_MAX - 1 + i] = (struct data_s){ 1, 0, 0, 0 };
	}
	for (i = KI_MAX - 2; i >= 0; i--) {
		ki[i] = merge(ki[i * 2 + 1], ki[i * 2 + 2]);
	}
	memset(ki_all_inv, 0, sizeof(ki_all_inv));
}

struct data_s ki_inv_i(int idx, int ss, int se, int qs, int qe) {
	if (se <= qs || qe <= ss) { /* 完全に外れている */
		/* 何もしない */
	} else if (qs <= ss && se <= qe) { /* セグメントがクエリに完全に含まれる */
		ki_all_inv[idx] = !ki_all_inv[idx];
	} else {
		int sm = ss + (se - ss) / 2;
		if (ki_all_inv[idx]) {
			ki_all_inv[idx * 2 + 1] = !ki_all_inv[idx * 2 + 1];
			ki_all_inv[idx * 2 + 2] = !ki_all_inv[idx * 2 + 2];
			ki_all_inv[idx] = 0;
		}
		ki[idx] = merge(
			ki_inv_i(idx * 2 + 1, ss, sm, qs, qe),
			ki_inv_i(idx * 2 + 2, sm, se, qs, qe)
		);
	}
	return ki_all_inv[idx] ? inv(ki[idx]) : ki[idx];
}

void ki_inv(int qs, int qe) {
	ki_inv_i(0, 0, KI_MAX, qs, qe);
}

struct data_s ki_get_i(int idx, int ss, int se, int qs, int qe) {
	struct data_s res;
	if (qe <= ss || se <= qs) { /* 完全に外れている */
		res = (struct data_s){0, 0, 0, 0};
	} else if (qs <= ss && se <= qe) { /* セグメントがクエリに完全に含まれる */
		res = ki[idx];
	} else {
		int sm = ss + (se - ss) / 2;
		res = merge(
			ki_get_i(idx * 2 + 1, ss, sm, qs, qe),
			ki_get_i(idx * 2 + 2, sm, se, qs, qe)
		);
	}
	return ki_all_inv[idx] ? inv(res) : res;
}

struct data_s ki_get(int qs, int qe) {
	return ki_get_i(0, 0, KI_MAX, qs, qe);
}

int N, Q;
int A[212345];
int T[212345], L[212345], R[212345];

int main(void) {
	int i;
	if (scanf("%d%d", &N, &Q) != 2) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d", &A[i]) != 1) return 1;
	}
	for (i = 0; i < Q; i++) {
		if (scanf("%d%d%d" ,&T[i], &L[i], &R[i]) != 3) return 1;
	}

	ki_init();
	for (i = 0; i < N; i++) {
		if (A[i] != 0) ki_inv(i, i + 1);
	}
	for (i = 0; i < Q; i++) {
		switch (T[i]) {
			case 1:
				ki_inv(L[i] - 1, R[i]);
				break;
			case 2:
				{
					struct data_s ans = ki_get(L[i] - 1, R[i]);
					printf("%" PRId64 "\n", ans.tentosu);
				}
				break;
		}
	}
	return 0;
}

/*

各区間について、以下の情報を持つ
・「0」の数
・「1」の数
・転倒数 (「1」の後にある「0」の数)
・逆転倒数 (「0」の後にある「1」の数)

inv操作
・「0」の数と「1」の数を入れ替える
・転倒数と逆転倒数を入れ替える

merge操作
・「0」の数を足す
・「1」の数を足す
・転倒数は、転倒数の和に、左の「1」の数×右の「0」の数を足す
・逆転倒数は、逆転倒数の和に、左の「0」の数×右の「1」の数を足す

*/

Submission Info

Submission Time
Task L - Lazy Segment Tree
User mikecat
Language C (gcc 12.2.0)
Score 100
Code Size 3481 Byte
Status AC
Exec Time 220 ms
Memory 17692 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 1
AC × 22
Set Name Test Cases
Sample 00-sample-01.txt
All 00-sample-01.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 01-12.txt, 01-13.txt, 01-14.txt, 01-15.txt, 01-16.txt, 01-17.txt, 01-18.txt, 01-19.txt, 01-20.txt, 01-21.txt
Case Name Status Exec Time Memory
00-sample-01.txt AC 6 ms 14524 KiB
01-01.txt AC 6 ms 14560 KiB
01-02.txt AC 170 ms 17064 KiB
01-03.txt AC 163 ms 17212 KiB
01-04.txt AC 26 ms 14792 KiB
01-05.txt AC 48 ms 15340 KiB
01-06.txt AC 128 ms 16364 KiB
01-07.txt AC 44 ms 15152 KiB
01-08.txt AC 118 ms 16240 KiB
01-09.txt AC 102 ms 16244 KiB
01-10.txt AC 86 ms 15864 KiB
01-11.txt AC 39 ms 15092 KiB
01-12.txt AC 214 ms 17684 KiB
01-13.txt AC 191 ms 17572 KiB
01-14.txt AC 213 ms 17644 KiB
01-15.txt AC 188 ms 17536 KiB
01-16.txt AC 214 ms 17568 KiB
01-17.txt AC 191 ms 17596 KiB
01-18.txt AC 220 ms 17560 KiB
01-19.txt AC 188 ms 17692 KiB
01-20.txt AC 210 ms 17676 KiB
01-21.txt AC 197 ms 17644 KiB


2025-11-29 (Sat)
05:36:19 +09:00