QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#449426#8518. Roars IIIluanmengleiWA 3ms16016kbC++174.9kb2024-06-21 10:05:282024-06-21 10:05:29

Judging History

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

  • [2024-06-21 10:05:29]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:16016kb
  • [2024-06-21 10:05:28]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

namespace SOL {

using i64 = long long;
void debug(const char *msg, ...) {
#ifdef CLESIP
    va_list arg;
    static char pbString[512];
    va_start(arg,msg);
    vsprintf(pbString,msg,arg);
    cerr << "[DEBUG] " << pbString << "\n";
    va_end(arg);
#endif    
}
template<typename T, typename L>
bool chkmax(T &x, L y) { if (x < y) return x = y, true; return false; }
template<typename T, typename L>
bool chkmin(T &x, L y) { if (y < x) return x = y, true; return false; }

const int N = 2e5 + 10;
int n, dfn[N], id[N], sze[N], cnt;
i64 ans[N];
char str[N];
vector<int> adj[N];

const int SEG_SIZE = N * 4;
struct SegTree {
	#define lc (x * 2)
	#define rc (x * 2 + 1)
	#define mid ((l + r) >> 1)

	int tag[SEG_SIZE];
	array<int, 2> cnt[SEG_SIZE], mx[SEG_SIZE]; 
	i64 sum[SEG_SIZE];

	void pull(int x) {
		mx[x] = max(mx[lc], mx[rc]);
		sum[x] = sum[lc] + sum[rc];
		for (int op : { 0, 1 })
			cnt[x][op] = cnt[lc][op] + cnt[rc][op];
	}

	void apply(int x, int k) {
		tag[x] += k;
		sum[x] += 1ll * k * (cnt[x][0] - cnt[x][1]);
		mx[x][0] += k;
	}

	void push(int x) {
		if (tag[x]) {
			apply(lc, tag[x]);
			apply(rc, tag[x]);
			tag[x] = 0;
		}
	}

	void set(int x, int l, int r, int p, int op, int k) {
		if (l == r) {
			cnt[x][op] = k;
			if (cnt[x][1])
				mx[x] = { tag[x], p };
			else
				mx[x] = { -1, 0 };
			sum[x] = tag[x] * (cnt[x][0] - cnt[x][1]);
			return;
		}
		push(x);
		p <= mid ? set(lc, l, mid, p, op, k) : set(rc, mid + 1, r, p, op, k);
		pull(x);
	}

	void add(int x, int l, int r, int ql, int qr, int k) {
		if (ql > qr)
			return;
		if (ql <= l && r <= qr)
			return apply(x, k);
		push(x);
		if (ql <= mid)
			add(lc, l, mid, ql, qr, k);
		if (mid < qr)
			add(rc, mid + 1, r, ql, qr, k);
		pull(x);
	}

	array<int, 2> query_max(int x, int l, int r, int ql, int qr) {
		if (ql > qr)
			return { -1, 0 };
		if (ql <= l && r <= qr)
			return mx[x];
		push(x);
		if (ql <= mid && mid < qr)
			return max(query_max(lc, l, mid, ql, qr), query_max(rc, mid + 1, r, ql, qr));
		else
			return ql <= mid ? query_max(lc, l, mid, ql, qr) : query_max(rc, mid + 1, r, ql, qr);
	}

	void debug_print(int x, int l, int r) {
		if (l == r) {
			debug("pos: %d x: %d (%d, %d) dep: %d", l, id[l], cnt[x][0], cnt[x][1], tag[x]);
			return;
		}
		push(x);
		debug_print(lc, l, mid);
		debug_print(rc, mid + 1, r);
	}

	#undef lc
	#undef rc
	#undef mid
} segt;

int pos[N];

void dfs1(int x, int p) {
	dfn[x] = ++ cnt, id[dfn[x]] = x, sze[x] = 1;
	for (int y : adj[x]) if (y != p) {
		dfs1(y, x);
		segt.add(1, 1, n, dfn[y], dfn[y] + sze[y] - 1, 1);
		sze[x] += sze[y];
	}
	if (str[x] == '0') {
		auto res = segt.query_max(1, 1, n, dfn[x], dfn[x] + sze[x] - 1);
		if (res[1] != 0) {
			pos[x] = id[res[1]];
			segt.set(1, 1, n, dfn[pos[x]], 1, 0);
			segt.set(1, 1, n, dfn[x], 1, 1);
		} 
	} else {
		segt.set(1, 1, n, dfn[x], 0, 1);
		segt.set(1, 1, n, dfn[x], 1, 1);
	}
}

void dfs2(int x, int p) {
	// cerr << "visit " << x << "\n";
	// segt.debug_print(1, 1, n);
	ans[x] = segt.sum[1];
	for (int y : adj[x]) if (y != p) {
		int tmpx = 0, tmpy = 0;
		if (pos[x]) {
			segt.set(1, 1, n, dfn[x], 1, 0);
			segt.set(1, 1, n, dfn[pos[x]], 1, 1);
		}
		if (pos[y]) {
			segt.set(1, 1, n, dfn[y], 1, 0);
			segt.set(1, 1, n, dfn[pos[y]], 1, 1);
		}
		segt.add(1, 1, n, dfn[y], dfn[y] + sze[y] - 1, -1);
		segt.add(1, 1, n, 1, dfn[y] - 1, 1);
		segt.add(1, 1, n, dfn[y] + sze[y], n, 1);
		if (str[x] == '0') {
			auto res = max(segt.query_max(1, 1, n, 1, dfn[y] - 1), segt.query_max(1, 1, n, dfn[y] + sze[y], n));
			if (res[1] != 0) {
				tmpx = id[res[1]];
				segt.set(1, 1, n, dfn[tmpx], 1, 0); 
				segt.set(1, 1, n, dfn[x], 1, 1); 
			}
		}
		if (str[y] == '0') {
			auto res = segt.mx[1];
			if (res[1] != 0) {
				tmpy = id[res[1]];
				segt.set(1, 1, n, dfn[tmpy], 1, 0); 
				segt.set(1, 1, n, dfn[y], 1, 1); 
			}
		}
		swap(pos[x], tmpx);
		swap(pos[y], tmpy);

		dfs2(y, x);

		swap(pos[x], tmpx);
		swap(pos[y], tmpy);
		if (tmpy) {
			segt.set(1, 1, n, dfn[y], 1, 0); 
			segt.set(1, 1, n, dfn[tmpy], 1, 1); 
		}
		if (tmpx) {
			segt.set(1, 1, n, dfn[x], 1, 0); 
			segt.set(1, 1, n, dfn[tmpx], 1, 1); 
		}
		segt.add(1, 1, n, dfn[y], dfn[y] + sze[y] - 1, 1);
		segt.add(1, 1, n, 1, dfn[y] - 1, -1);
		segt.add(1, 1, n, dfn[y] + sze[y], n, -1);
		if (pos[y]) {
			segt.set(1, 1, n, dfn[pos[y]], 1, 0);
			segt.set(1, 1, n, dfn[y], 1, 1);
		}
		if (pos[x]) {
			segt.set(1, 1, n, dfn[pos[x]], 1, 0);
			segt.set(1, 1, n, dfn[x], 1, 1);
		}
	}
}

void solve() {
	cin >> n >> (str + 1);
	for (int i = 1, x, y; i < n; i ++) {
		cin >> x >> y;
		adj[x].push_back(y), adj[y].push_back(x);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	for (int i = 1; i <= n; i ++)
		cout << ans[i] << " \n"[i == n];
}

}
int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	SOL::solve();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

5
10101
1 2
2 3
2 4
4 5

output:

2 2 2 3 3

result:

ok 5 number(s): "2 2 2 3 3"

Test #2:

score: 0
Accepted
time: 2ms
memory: 9740kb

input:

1
0

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 0ms
memory: 15864kb

input:

1
1

output:

0

result:

ok 1 number(s): "0"

Test #4:

score: 0
Accepted
time: 0ms
memory: 11844kb

input:

2
10
1 2

output:

0 1

result:

ok 2 number(s): "0 1"

Test #5:

score: 0
Accepted
time: 1ms
memory: 11772kb

input:

3
100
2 3
2 1

output:

0 1 2

result:

ok 3 number(s): "0 1 2"

Test #6:

score: 0
Accepted
time: 2ms
memory: 11928kb

input:

4
1100
4 1
4 3
4 2

output:

1 1 3 1

result:

ok 4 number(s): "1 1 3 1"

Test #7:

score: -100
Wrong Answer
time: 0ms
memory: 11776kb

input:

5
10100
4 5
1 3
2 1
3 5

output:

0 0 0 0 0

result:

wrong answer 2nd numbers differ - expected: '2', found: '0'