QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#347206 | #7736. Red Black Tree | ucup-team3160# | RE | 0ms | 31956kb | C++17 | 5.6kb | 2024-03-09 12:17:46 | 2024-03-09 12:17:47 |
Judging History
answer
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#include "lib.h"
#endif
#define rep(i, min, max) for(int i = (min); i <= (max); ++i)
#define nrep(i, max, min) for(int i = (max); i >= (min); --i)
#define reads(str) (scanf("%s", str + 1), strlen(str + 1))
#define case() int Ts = read(); rep(T, 1, Ts)
#define putf(flag) puts((flag) ? "YES" : "NO")
#define put(x) printf("%d ", x)
#define putl(x) printf("%lld ", x)
#define endl() putchar('\n')
using namespace std;
typedef long long ll;
inline int read()
{
int now=0; bool nev=false; char c=getchar();
while(c<'0' || c>'9') { if(c=='-') nev=true; c=getchar(); }
while(c>='0' && c<='9') { now=(now<<1)+(now<<3)+(c&15); c=getchar(); }
return nev?-now:now;
}
const int N = 1e6 + 10;
mt19937 rnd((ll) new char);
namespace Treap {
int siz[N], val[N], add[N], ls[N], rs[N], key[N];
ll sum[N];
int alloc;
void mt(int x, int v) {
if(!x) return;
val[x] += v;
add[x] += v;
sum[x] += v * siz[x];
}
void pd(int x) {
if(add[x]) mt(ls[x], add[x]), mt(rs[x], add[x]), add[x] = 0;
}
void pu(int x) {
if(!x) return;
siz[x] = siz[ls[x]] + siz[rs[x]] + 1;
sum[x] = sum[ls[x]] + sum[rs[x]] + val[x];
}
void splv(int x, int v, int& pl, int& pr) {
pd(x);
if(!x) return pl = pr = 0, void();
if(val[x] <= v) pl = x, splv(rs[x], v, rs[pl], pr);
else pr = x, splv(ls[x], v, pl, ls[pr]);
pu(x);
}
void splsz(int x, int k, int &pl, int &pr) {
pd(x);
if(!x) return pl = pr = 0, void();
if(k <= siz[ls[x]]) {
pr = x;
splsz(ls[x], k, pl, ls[pr]);
} else if(siz[ls[x]] + 1 == k) {
pl = x, pr = rs[x], rs[x] = 0;
} else {
pl = x;
splsz(rs[x], k - siz[ls[x]] - 1, rs[pl], pr);
}
pu(pl), pu(pr);
// print("siz", pl, pr, siz[pl], siz[pr]);
}
int merge(int x, int y) {
pd(x), pd(y);
if(!x || !y) return x | y;
if(key[x] < key[y]) return ls[y] = merge(x, ls[y]), pu(y), y;
else return rs[x] = merge(rs[x], y), pu(x), x;
}
int make(int v) {
int x = ++alloc;
val[x] = v, sum[x] = v, add[x] = 0, key[x] = rnd(), siz[x] = 1;
return x;
}
void dfs(int x, vector<int> &vec) {
if(!x) return;
pd(x);
dfs(ls[x], vec);
vec.push_back(val[x]);
dfs(rs[x], vec);
}
void prt(int x) {
if(!x) return;
pd(x);
// print(x, ls[x], rs[x], siz[x], val[x], sum[x]);
prt(ls[x]);
prt(rs[x]);
}
struct node {
int rt;
node() { rt = 0; }
void ins(int v) {
int x = 0, y = 0;
splv(rt, v, x, y), rt = merge(merge(x, make(v)), y);
}
void del(int v) {
int x = 0, y = 0, z = 0;
splv(rt, v, x, z), splv(x, v - 1, x, y);
y = merge(ls[y], rs[y]);
rt = merge(merge(x, y), z);
}
int kth(int x, int k) {
int lsiz = siz[ls[x]];
if(k <= lsiz) return kth(ls[x], k);
if(k == lsiz + 1) return val[x];
return kth(rs[x], k - lsiz - 1);
}
void addpre(int k, int v) {
int x = 0, y = 0;
splsz(rt, k, x, y);
if(x) mt(x, v);
rt = merge(x, y);
}
void addsuf(int k, int v) {
int x = 0, y = 0;
splsz(rt, k, x, y);
if(y) mt(y, v);
rt = merge(x, y);
}
ll qrypre(int k) {
int x = 0, y = 0;
splsz(rt, k, x, y);
ll ans = sum[x];
rt = merge(x, y);
return ans;
}
void print() {
// prt(rt);
// end();
}
};
node merge(node x, node y) {
if(siz[x.rt] < siz[y.rt]) swap(x, y);
vector<int> vec;
dfs(y.rt, vec);
for(int v : vec) x.ins(v);
return x;
}
} using namespace Treap;
char s[N];
int col[N], cnt[N];
vector<int> to[N];
ll ans[N];
node rt[N];
int main() {
case() {
int n = read();
reads(s);
rep(i, 1, n) col[i] = s[i] - '0';
rep(i, 2, n) to[read()].push_back(i);
nrep(x, n, 1) {
cnt[x] = 0;
for(int y : to[x]) rt[x] = merge(rt[x], rt[y]), cnt[x] += cnt[y];
// cnt[x] += col[x];
if(!to[x].size()) {
if(col[x] == 0) {
rt[x].ins(0);
}
if(col[x] == 1) {
cnt[x] ++;
rt[x].ins(1);
}
} else {
rt[x].ins(0);
// vector<int> vec2;
// dfs(rt[x].rt, vec2);
// putnl(x, ':'), plist(vec2);
if(col[x] == 0) {
rt[x].addsuf(cnt[x], 1);
}
if(col[x] == 1) {
cnt[x] ++;
rt[x].addsuf(cnt[x] - 1, 1);
}
// rt[x].print();
// vector<int> vec;
// dfs(rt[x].rt, vec);
// putnl(x, ':'), plist(vec);
// putnl(x, ':'), print(cnt[x], rt[x].qrypre(cnt[x]));
// rt[x].print();
}
ans[x] = cnt[x] - rt[x].qrypre(cnt[x]);
}
rep(i, 1, n) putl(ans[i]); endl();
rep(i, 1, n) to[i] = {}, rt[i] = {};
}
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 31956kb
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
Runtime Error
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 1 0 0 0 0 0 6 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 2 2 2 1 1 0 0 2 0 1 0 0 0 0 3 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 4 4 1 0 3 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 7 5 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 2 2 0 0 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0...