社区讨论
萌新95分求助!!!!!!WA第16个点, 求大佬指点
P2146[NOI2015] 软件包管理器参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo2cgeqv
- 此快照首次捕获于
- 2023/10/23 11:34 2 年前
- 此快照最后确认于
- 2023/11/03 11:43 2 年前
C
#include<bits/stdc++.h>
using namespace std;
//#define LL long long
const int MAX = 3e5 + 70;
int n, m, q, tot, head[MAX], dep[MAX], id, siz[MAX], in_l[MAX], in_r[MAX];
int num, dfn[MAX], nfd[MAX], bel[MAX], f[MAX];
struct made {
int l, t;
}edge[MAX * 2];
void add(int u, int v) {
edge[++tot].l = head[u];
edge[tot].t = v;
head[u] = tot;
}
struct SegmentTree {
int l, r, bol, dat;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define bol(x) tree[x].bol
#define dat(x) tree[x].dat
}tree[MAX * 4];
char s[MAX];
void dfs_size(int x, int fa) {
f[x] = fa, siz[x] = 1, dep[x] = dep[fa] + 1;
for(int i = head[x]; i; i = edge[i].l) {
int t = edge[i].t;
if(t == fa) continue;
dfs_size(t, x);
siz[x] += siz[t];
}
}
void dfs(int p, int chain) {
int k = n + 2; dfn[p] = ++num; bel[p] = chain; nfd[num] = p; in_l[p] = num;
for(int i = head[p]; i; i = edge[i].l) {
int t = edge[i].t;
if(dep[t] == dep[p] + 1) if(siz[t] > siz[k]) k = t;
}
if(k != n + 2) dfs(k, chain);
for(int i = head[p]; i; i = edge[i].l) {
int t = edge[i].t;
if(dep[t] == dep[p] + 1 && t != k) dfs(t, t);
}
in_r[p] = num;
}
void build(int p, int l, int r) {
l(p) = l; r(p) = r; bol(p) = 0, dat(p) = -1;
if(l(p) == r(p)) return ;
int mid = (l + r) / 2;
build(2 * p, l, mid);
build(2 * p + 1, mid + 1, r);
}
void spread(int p) {
if(dat(p) != -1) {
dat(2 * p) = dat(2 * p + 1) = dat(p);
bol(2 * p) = (dat(p) == 1 ? (r(2 * p) - l(2 * p) + 1) : 0);
bol(2 * p + 1) = (dat(p) == 1 ? (r(2 * p + 1) - l(2 * p + 1) + 1) : 0);
dat(p) = -1;
}
}
int find(int p, int l, int r, int val) {
int ans = 0;
if(l(p) >= l && r(p) <= r) {
if(val == 0) return (r(p) - l(p) + 1) - bol(p);
else return bol(p);
}
spread(p);
int mid = (l(p) + r(p)) / 2;
if(mid >= r) ans += find(2 * p, l, r, val);
else if(mid < l) ans += find(2 * p + 1, l, r, val);
else {
ans += find(2 * p, l, r, val);
ans += find(2 * p + 1, l, r, val);
}
return ans;
}
void change(int p, int l, int r, int val) {
if(l(p) >= l && r(p) <= r) {
if(val == 0) {
bol(p) = 0;
dat(p) = 0;
}
else {
bol(p) = (r(p) - l(p) + 1);
dat(p) = 1;
}
return ;
}
spread(p);
int mid = (l(p) + r(p)) / 2;
if(mid >= r) change(2 * p, l, r, val);
else if(mid < l) change(2 * p + 1, l, r, val);
else {
change(2 * p, l, r, val);
change(2 * p + 1, l, r, val);
}
bol(p) = bol(2 * p) + bol(2 * p + 1);
}
int Q(int u, int v, int val) {
int ans = 0;
while(bel[u] != bel[v]) {
ans += find(1, dfn[bel[u]], dfn[u], 0);
change(1, dfn[bel[u]], dfn[u], 1);
u = f[bel[u]];
}
ans += find(1, dfn[v], dfn[u], 0);
change(1, dfn[v], dfn[u], 1);
return ans;
}
int main() {
// freopen("manager.in","r",stdin);
// freopen("manager.out","w",stdout);
scanf("%d", &n);
for(int i = 1; i < n; i++) {
int v;
scanf("%d", &v);
add(v, i);
}
dfs_size(0, 0);
dfs(0, 1);
build(1, 1, n);
scanf("%d", &q);
for(int i = 1; i <= q; i++) {
scanf("%s", s + 1);
scanf("%d", &id);
if(s[1] == 'i') {
int ans = Q(id, 0, 0);
printf("%d\n", ans);
}
else {
int ans = find(1, in_l[id], in_r[id], 1);
change(1, in_l[id], in_r[id], 0);
printf("%d\n", ans);
}
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...