QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#444217#8518. Roars IIIucup-team266#ML 0ms13944kbC++235.5kb2024-06-15 17:49:042024-06-15 17:49:10

Judging History

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

  • [2024-06-15 17:49:10]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:13944kb
  • [2024-06-15 17:49:04]
  • 提交

answer

#include<bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define int long long 
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef array<int, 3> ai3;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int Mod = 1e9 + 7;
inline void uadd(int &a, int b){ a += b-Mod; a += (a>>31) & Mod; }
inline void usub(int &a, int b){ a -= b, a += (a>>31) & Mod; }
inline void umul(int &a, int b){ a = (int)(1ll * a * b % Mod); }
inline int add(int a, int b){ a += b-Mod; a += (a>>31) & Mod; return a; }
inline int sub(int a, int b){ a -= b, a += (a>>31) & Mod; return a; }
inline int mul(int a, int b){ a = (int)(1ll * a * b % Mod); return a; }
int qpow(int b, ll p){ int ret = 1; while(p){ if(p&1) umul(ret, b); umul(b, b), p >>= 1; } return ret; }
const int fN = 10010;
int fact[fN], invfact[fN], pw2[fN], invpw2[fN], inv[fN];
void initfact(int n){
	pw2[0] = 1; for(int i = 1; i <= n; ++i) pw2[i] = mul(pw2[i-1], 2);
	invpw2[0] = 1; for(int i = 1; i <= n; ++i) invpw2[i] = mul(invpw2[i-1], (Mod+1) / 2);
	fact[0] = 1; for(int i = 1; i <= n; ++i) fact[i] = mul(fact[i-1], i);
	invfact[n] = qpow(fact[n], Mod-2); for(int i = n; i > 0; --i) invfact[i-1] = mul(invfact[i], i);
	for(int i = 1; i <= n; ++i) inv[i] = mul(invfact[i], fact[i-1]);
}
int binom(int n, int m){ return (m < 0 || m > n) ? 0 : mul(fact[n], mul(invfact[m], invfact[n-m])); }
const double pi = acos(-1);
template<typename T> inline void chmax(T &_a, T _b){ (_a<_b) ? (_a=_b) : 0; }
template<typename T> inline void chmin(T &_a, T _b){ (_b<_a) ? (_a=_b) : 0; }
mt19937_64 rng(58);
inline int myrand(int l, int r){ return (int)(rng() % (r-l+1)) + l; }

int n;
string s; int has[200200];
vi g[200200];
int ord[200200], lind[200200], rind[200200], cp = 0;

namespace seg{
	pii mx[525252]; ll sum[525252]; int tag[525252];
	void pushtag(int l, int r, int k, int v){
		tag[k] += v;
		mx[k].first += v;
		sum[k] += 1ll * (r-l+1) * v;
	}
	void pushdown(int l, int r, int k){
		int mid = (l+r) >> 1;
		pushtag(l, mid, k+k, tag[k]), pushtag(mid+1, r, k+k+1, tag[k]);
		tag[k] = 0;
	}
	void build(int l, int r, int k){
		if(l == r) return mx[k] = make_pair(0, l), void();
		int mid = (l+r) >> 1;
		build(l, mid, k+k), build(mid+1, r, k+k+1);
		mx[k] = max(mx[k+k], mx[k+k+1]);
	}
	void segupd(int tl, int tr, int v, int l, int r, int k){
		if(l > tr || tl > r) return ;
		if(tl <= l && r <= tr) return pushtag(l, r, k, v);
		pushdown(l, r, k);
		int mid = (l+r) >> 1;
		segupd(tl, tr, v, l, mid, k+k), segupd(tl, tr, v, mid+1, r, k+k+1);
		sum[k] = sum[k+k] + sum[k+k+1], mx[k] = max(mx[k+k], mx[k+k+1]);
	}
	void pntupd(int p, int v, int l, int r, int k){
		if(l == r) return mx[k] = make_pair(v, p), sum[k] = v, void();
		pushdown(l, r, k);
		int mid = (l+r) >> 1;
		(p <= mid) ? pntupd(p, v, l, mid, k+k) : pntupd(p, v, mid+1, r, k+k+1);
		sum[k] = sum[k+k] + sum[k+k+1], mx[k] = max(mx[k+k], mx[k+k+1]);
	}
	pii qry(int tl, int tr, int l, int r, int k){
		if(l > tr || tl > r) return make_pair(-1, -1);
		if(tl <= l && r <= tr) return mx[k];
		pushdown(l, r, k);
		int mid = (l+r) >> 1;
		return max(qry(tl, tr, l, mid, k+k), qry(tl, tr, mid+1, r, k+k+1));
	}
}

int op[200200], opval[200200]; ll sum[200200], ans[200200];

void dfs0(int u, int fa){
	lind[u] = cp;
	has[u] = (s[u] == '1');
	if(has[u]){
		ord[cp++] = u, --sum[u];
	}
	for(auto t : g[u]){
		if(t == fa) continue;
		dfs0(t, u);
		sum[u] += sum[t];
	}
	rind[u] = cp;
	sum[u] += (rind[u] - lind[u]);
}

void dfs1(int u, int fa){
	for(auto t : g[u]){
		if(t == fa) continue;
		dfs1(t, u);
	}
	seg::segupd(lind[u] + has[u], rind[u] - 1, 1, 0, cp - 1, 1);
	if(!has[u]){
		pii ret = seg::qry(lind[u], rind[u] - 1, 0, cp - 1, 1);
		op[u] = ret.second, opval[u] = ret.first;
		if(opval[u] >= 0) seg::pntupd(opval[u], 0, 0, cp - 1, 1);
	}
}

void dfs2(int u, int fa){
	if(!has[u]){
		//cout << " " << u << ": " << op[u] << " " << opval[u] << endl;
		if(op[u] >= 0) seg::pntupd(op[u], opval[u], 0, cp - 1, 1);
		ans[u] = seg::sum[1] - seg::mx[1].first;
	} else {
		ans[u] = seg::sum[1];
	}
	//cout << u << ": ";
	//rep(i, cp) cout << dep[i] << " ";
	//cout << endl;

	for(auto t : g[u]){
		if(t == fa) continue;

		int curmx = -1, curop = -1;
		if(!has[u]){
			pii ret = max(seg::qry(0, lind[t] - 1, 0, cp - 1, 1), seg::qry(rind[t], cp - 1, 0, cp - 1, 1));
			curmx = ret.first, curop = ret.second;
		}
		if(curop >= 0) seg::pntupd(curop, 0, 0, cp - 1, 1);
		seg::segupd(0, lind[t] - 1, 1, 0, cp - 1, 1), seg::segupd(lind[t], rind[t] - 1, -1, 0, cp - 1, 1), seg::segupd(rind[t], cp - 1, 1, 0, cp - 1, 1);

		sum[t] = sum[u] + (cp - 2 * (rind[t] - lind[t]));
		dfs2(t, u);

		seg::segupd(0, lind[t] - 1, -1, 0, cp - 1, 1), seg::segupd(lind[t], rind[t] - 1, 1, 0, cp - 1, 1), seg::segupd(rind[t], cp - 1, -1, 0, cp - 1, 1);
		if(curop >= 0) seg::pntupd(curop, curmx, 0, cp - 1, 1);
	}

	if(!has[u] && op[u] >= 0) seg::pntupd(op[u], 0, 0, cp - 1, 1);
}

signed main(){
//	freopen("b.in", "r", stdin);
//	freopen("b.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> s;
	rep(i, n-1){
		int u, v;
		cin >> u >> v;
		--u, --v;
		g[u].push_back(v), g[v].push_back(u);
	}

	dfs0(0, -1);
	seg::build(0, cp - 1, 1);

	dfs1(0, -1);

	dfs2(0, -1);

	//rep(i, n) cout << i << ": " << sum[i] << " " << ans[i] << endl;

	rep(i, n) cout << sum[i] - ans[i] << " ";
	cout << "\n";

	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 13944kb

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: -100
Memory Limit Exceeded

input:

1
0

output:


result: