QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#267113#7736. Red Black TreeBoulevardDustWA 201ms52004kbC++204.8kb2023-11-26 22:47:022023-11-26 22:47:02

Judging History

你现在查看的是最新测评结果

  • [2024-02-19 10:14:05]
  • hack成功,自动添加数据
  • (/hack/538)
  • [2023-11-26 22:47:02]
  • 评测
  • 测评结果:WA
  • 用时:201ms
  • 内存:52004kb
  • [2023-11-26 22:47:02]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define see(x) cerr << x << " "
#define seeln(x) cerr << x << endl
#define out(x) cerr << #x << " = " << x << " "
#define outln(x) cerr << #x << " = " << x << endl

#define re
inline void Rd(int &res){
    re char c;res=0;
    while(c=getchar(),c<48);
    do res=(res<<3)+(res<<1)+(c^48);
    while(c=getchar(),c>47);
}

const int N = 100005;
int n;
int col[N];
char str[N];
vector<int> G[N];

struct node {
	int src;
	int cnt;
	int k;
};

const int inf = 1000000000;
int len[N];
int ans[N];
int Log[N];
int vA[N][19], vB[N][19];

void dfs(int x) {
	if (G[x].empty()) {
		len[x] = 1;
		return;
	}
	len[x] = inf;
	for (int y : G[x]) {
		dfs(y);
		if (len[y] + 1 < len[x]) {
			len[x] = len[y] + 1;
		}
	}
}

#define sz(x) (int)(x.size())
vector<int> dp[N], Dp[N];
int sum[N];
node cur[N];

int calcdp(int x, int id) {
	// out(x); out(id); outln(sz(dp[x]));
	if (id < 0 || id > len[x]) return inf;
	return dp[x][id];
}
int calcDp(int x, int id) {
	if (id < 0 || id > len[x]) return inf;
	return Dp[x][id];
}

int qA(int l, int r) {
	int k = Log[r - l + 1];
	return min(vA[l][k], vA[r - (1 << k) + 1][k]);
}
int qB(int l, int r) {
	int k = Log[r - l + 1];
	return min(vB[l][k], vB[r - (1 << k) + 1][k]);
}

void calc_top(int x) {
	int y = cur[x].src;
	int k = cur[x].k;
	int cnt = cur[x].cnt;
	// out(x); out(y); out(k); outln(cnt);
	Dp[x].resize(len[x] + 1);
	for (int i = 0; i <= len[x]; ++i) {
		Dp[x][i] = inf;
		vA[i][0] = vB[i][0] = inf;
	}
	for (int i = 0; i <= len[y] && i <= len[x]; ++i) {
		vA[i][0] = dp[y][i] + i;
		vB[i][0] = dp[y][i] - i;
		// out(i); out(vA[i][0]); outln(vB[i][0]);
	}
	for (int i = 1; i <= Log[len[x]]; ++i) {
		for (int j = 0; j <= len[x] - (1 << i) + 1; ++j) {
			vA[j][i] = min(vA[j][i - 1], vA[j + (1 << (i - 1))][i - 1]);
			vB[j][i] = min(vB[j][i - 1], vB[j + (1 << (i - 1))][i - 1]);
		}
	}
	for (int i = 0; i <= len[x]; ++i) {
		/*for (int j = 0; j <= i && j <= k; ++j) {
			Dp[x][i] = min(Dp[x][i], calcdp(y, i - j) + abs(cnt - j));
		}*/
		int s1, s2;
		s1 = i - min(i, min(k, cnt)), s2 = i - 0;
		if (s1 <= s2) {
			Dp[x][i] = min(Dp[x][i], qA(s1, s2)) + cnt - i;
			/*for (int k = s1; k <= s2; ++k) {
				Dp[x][i] = min(Dp[x][i], calcdp(y, k) + k + cnt - i);
			}*/
		}
		s1 = i - min(i, k), s2 = i - (cnt + 1);
		if (s1 <= s2) {
			Dp[x][i] = min(Dp[x][i], qB(s1, s2)) + i - cnt;
			/*for (int k = s1; k <= s2; ++k) {
				Dp[x][i] = min(Dp[x][i], calcdp(y, k) + k + i - cnt);
			}*/
		}
		/*for (int j = 0; j <= i && j <= k && j <= cnt; ++j) {
			Dp[x][i] = min(Dp[x][i], calcdp(y, i - j) + i - j + cnt - i);
		}
		for (int j = cnt + 1; j <= i && j <= k; ++j) {
			Dp[x][i] = min(Dp[x][i], calcdp(y, i - j) + j - i + i - cnt);
		}*/
	}
}

node run(int x) {
	if (sz(G[x]) == 0) {
		cur[x] = (node){x, 0, 0};
		dp[x] = {0, 0};
		if (col[x]) dp[x][0] = 1;
		else dp[x][1] = 1;
		// out(x); outln(cur[x].src);
		return cur[x];
	}
	if (sz(G[x]) == 1) {
		node tmp = run(G[x][0]);
		tmp.k += 1;
		tmp.cnt += col[x];
		ans[x] = ans[G[x][0]];
		cur[x] = tmp;
		return tmp;
	}
	for (int y : G[x]) run(y);


	// see("run"); outln(x);


	dp[x].resize(len[x] + 1);
	for (int i = 0; i <= len[x]; ++i) {
		sum[i] = 0;
		dp[x][i] = inf;
	}
	for (int y : G[x]) {
		if (dp[y].empty()) {
			calc_top(y);
			for (int i = 0; i <= len[x]; ++i) {
				sum[i] = min(sum[i] + calcDp(y, i), inf);
			}
		} else {
			for (int i = 0; i <= len[x]; ++i) {
				sum[i] = min(sum[i] + calcdp(y, i), inf);
			}
		}
	}


	if (col[x]) {
		for (int h = 0; h <= len[x]; ++h) {
			int tmp = inf;
			tmp = min(tmp, sum[h] + 1);
			if (h) tmp = min(tmp, sum[h - 1]);
			dp[x][h] = tmp;
		}
	} else {
		for (int h = 0; h <= len[x]; ++h) {
			int tmp = inf;
			tmp = min(tmp, sum[h]);
			if (h) tmp = min(tmp, sum[h - 1] + 1);
			dp[x][h] = tmp;
		}
	}
	ans[x] = inf;
	for (int i = 0; i <= len[x]; ++i) {
		ans[x] = min(ans[x], dp[x][i]);
	}
	return (node){x, 0, 0};
}

void clear() {
	for (int i = 1; i <= n; ++i) {
		G[i].clear();
		dp[i].clear();
		Dp[i].clear();
	}
	for (int i = 0; i <= n; ++i) sum[i] = 0;
	for (int i = 0; i <= n; ++i) col[i] = 0;
	for (int i = 0; i <= n; ++i) len[i] = 0;
	for (int i = 0; i <= n; ++i) ans[i] = 0;
	for (int i = 0; i <= n; ++i) cur[i] = (node){0, 0, 0};
}

int main() {
	int T; Rd(T); while (T--) {
		Rd(n);
		scanf("%s", str + 1);
		for (int i = 1; i <= n; ++i) col[i] = str[i] - 48;
		Log[0] = -1; for (int i = 1; i <= n; ++i) Log[i] = Log[i >> 1] + 1;
		for (int i = 2; i <= n; ++i) {
			int u; scanf("%d", &u);
			G[u].push_back(i);
		}
		dfs(1); run(1);
		for (int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]);
		clear();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 16804kb

input:

2
9
101011110
1 1 3 3 3 6 2 2
4
1011
1 1 3

output:

4 1 2 0 0 0 0 0 0
2 0 0 0

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 201ms
memory: 52004kb

input:

6107
12
000000001000
1 2 3 2 5 4 4 7 3 8 11
19
1100111101111011110
1 2 1 1 4 5 2 4 3 2 2 7 10 2 11 3 15 5
7
0111110
1 1 2 2 1 5
3
000
1 1
7
1000011
1 2 3 3 5 4
7
0001001
1 1 1 3 5 3
8
00111000
1 1 3 2 5 2 7
11
11111110111
1 1 1 4 5 4 5 2 5 1
15
110101101000010
1 2 3 2 1 5 2 5 6 5 8 7 9 14
10
0101000...

output:

1 1 1 1 0 0 0 0 0 0 0 0
6 2 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0
0 0 0
2 2 2 0 0 0 0
2 0 1 0 0 0 0
2 1 0 0 0 0 0 0
4 0 0 2 1 0 0 0 0 0 0
4 4 0 0 2 0 0 0 0 0 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0
6 5 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
1 1 0 0 0
5 1 0 1 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0 0
6 4 ...

result:

wrong answer 5th lines differ - expected: '0 0 0 0 0 0 0', found: '2 2 2 0 0 0 0'