QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#444217 | #8518. Roars III | ucup-team266# | ML | 0ms | 13944kb | C++23 | 5.5kb | 2024-06-15 17:49:04 | 2024-06-15 17:49:10 |
Judging History
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