求 hack
查看原帖
求 hack
406941
Register_int-std=c++14楼主2024/12/25 20:59

rt,这个在我们模拟赛里面。我场上做法是这样的:

转化为对所有 (i,j)(i,j) 的数量,满足在他的同一连通块中不存在 (i,j)(i',j') 使得 j>jj'>j 或者 j=jj'=ji>ii'>i。分别统计。

感觉情况分的很全了,但是 WA 一半,求 hack /kel

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAXN = 1e6 + 10;

int T, n, a[MAXN], c1[MAXN], c0[MAXN], p1[MAXN], p0[MAXN];

int pa, pb, pc; ll ans;

int main() {
	for (scanf("%d", &T); T--; ) {
		scanf("%d", &n), ans = 0, pa = pb = pc = n + 1;
		for (int i = 1; i <= n; i++) scanf("%d", &a[i]), p0[i] = p1[i] = n + 1;
		for (int i = 1, j = 0; i <= n; i++) {
			c1[i] = c1[i - 1], c0[i] = c0[i - 1];
			(a[i] ? p1 : p0)[++(a[i] ? c1[i] : c0[i])] = i;
		}
		for (int i = n; i; i--) {
			if (a[i]) pa = i;
			if (a[i] && c0[i]) pb = i;
			if (a[i] && c0[i] > 1) pc = i;
		}
		for (int i = 1, j = 0, k = 0; i <= n; i++) {
			ans += i - 1;
			if (a[i]) {
				/*1 1*/
				// nah
				/*0 1*/
			//	puts("0 1");
				if (c0[i] != c0[n]) ans -= c0[i]/*, printf("%d:%lld\n", i, c0[i])*/;
				else if (c1[i] != c1[n]) {
					if (c0[i]) ans -= c0[i] - 1/*, printf("%d:%lld\n", i, c0[i] - 1)*/;
				} else if (p1[1] < i) {
					if (c0[p1[1]] != c0[i]) ans -= c0[i] - c0[p1[1]] - 1/*, printf("%d:%lld\n", i, c0[i] - c0[p1[1]] - 1)*/;
					if (p1[1] > 2 && c0[i] - c0[p1[1]] >= 2) ans -= c0[p1[1]] - 1/*, printf("%d:%lld\n", i, c0[p1[1]] - 1)*/;
				} 
				k = i;
			} else {
				/*1 0*/
			//	puts("1 0");
				if (c0[i] != c0[n]) ans -= c1[i]/*, printf("%d:%d\n", i, c1[i])*/;
				else {
					if (c1[i] != c1[n]) {
						if (p0[2] <= j) ans -= c1[p0[2]] - c1[p0[1]]/*, printf("%d:%d\n", i, c1[p0[2]] - c1[p0[1]])*/;
						if (p0[2] < i) ans -= c1[i] - c1[p0[2]]/*, printf("%d:%d\n", i, c1[i] - c1[p0[2]])*/;
					} else {
						if (p0[1] < j) ans -= c1[j] - c1[p0[1]]/*, printf("%d:%d\n", i, c1[j] - c1[p0[1]])*/;
						if (p0[2] <= j) ans -= c1[i] - c1[j] - 1/*, printf("%d:%d\n", i, c1[i] - c1[j] - 1)*/;
					}
				}
				/*0 0*/
			//	puts("0 0");
				if (c1[i] != c1[n]) ans -= c0[i - 1]/*, printf("%d:%d\n", i, c0[i - 1])*/;
				else if (c0[i] != c0[n]) {
					if (p1[1] < i) ans -= c0[i - 1] - c0[p1[1]]/*, printf("%d:%d\n", i, c0[i - 1] - c0[p1[1]])*/;
				}  else {
					if (pa < pb && pb <= k) ans -= c0[pb] - c0[pa] - 1/*, printf("%d:%d\n", i, c0[pb] - c0[pa] - 1)*/;
					if (pb < pc && pb < j) ans -= c0[min(pc, j)] - c0[pb] - 1/*, printf("%d:%d\n", i, c0[min(pc, j)] - c0[pb] - 1)*/;
					if (pc < i) ans -= c0[i] - c0[pc] - 1/*, printf("%d:%d\n", i, c0[i] - c0[pc] - 1)*/;
				}
				j = i;
			}
		}
		printf("%lld\n", ans);
	}
}
2024/12/25 20:59
加载中...