树链剖分 - AcWing 918 - 软件包管理器
树链剖分 - AcWing 918 - 软件包管理器
这道题也挺板的,线段树的lazy维护区间置数即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5, M = N<<2;
int n, m;
int a, b, x;
char op[20];
// seg
int tree[N<<2];
int lazy[N<<2];
void push_up(int rt){
tree[rt] = tree[rt<<1] + tree[rt<<1|1];
}
void push_down(int rt, int l, int r){
if(lazy[rt] != -1){
int mid = l+r>>1;
tree[rt<<1] = (mid-l+1) * lazy[rt];
tree[rt<<1|1] = (r-mid) * lazy[rt];
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
lazy[rt] = -1;
}
}
void modify(int rt, int l, int r,int ml, int mr, int v){
if(ml <= l && mr >= r){
tree[rt] = (r-l+1)*v;
lazy[rt] = v;
}else{
push_down(rt, l, r);
int mid = l+r>>1;
if(ml <= mid){
modify(rt<<1, l, mid, ml, mr, v);
}
if(mr > mid){
modify(rt<<1|1, mid+1, r, ml, mr, v);
}
push_up(rt);
}
}
int query(int rt, int l, int r, int ql, int qr){
if(ql <= l && qr >= r){
return tree[rt];
}else{
push_down(rt, l, r);
int ans = 0;
int mid = l+r>>1;
if(ql <= mid){
ans += query(rt<<1, l, mid, ql, qr);
}
if(qr > mid){
ans += query(rt<<1|1, mid+1, r, ql, qr);
}
return ans;
}
}
// lct
vector<int> edges[N];
int fa[N];
int head[N];
int dep[N];
int heavy_son[N];
int dfs_id[N];
int subtree_begin[N];
int subtree_end[N];
int dfs1(int cur, int depth){
dep[cur] = depth;
int tot_size = 1, cur_size = 0,max_size = 0, max_root = 0;
for(auto it = edges[cur].begin(); it != edges[cur].end(); ++it){
cur_size = dfs1(*it, depth+1);
tot_size += cur_size;
if(cur_size > max_size){
max_size = cur_size;
max_root = *it;
}
}
heavy_son[cur] = max_root;
return tot_size;
}
void dfs2(int cur, int head_node, int& id){
head[cur] = head_node;
dfs_id[cur] = id++;
if(heavy_son[cur]){
dfs2(heavy_son[cur], head_node, id);
}
for(auto it = edges[cur].begin(); it != edges[cur].end(); ++it){
if(*it == heavy_son[cur]) continue;
dfs2(*it, *it, id);
}
subtree_begin[cur] = dfs_id[cur];
subtree_end[cur] = id-1;
}
void build_lct(){
int id = 1;
dfs1(1, 1);
dfs2(1, 1, id);
}
void modify_lct(int a, int b,int v){
int ha, hb;
while(1){
ha = head[a];
hb = head[b];
if(ha == hb){
a = dfs_id[a];
b = dfs_id[b];
if(a > b) swap(a, b);
modify(1, 1, n, a, b, v);
break;
}else{
if(dep[ha] < dep[hb]){
swap(a, b);
swap(ha, hb);
}
modify(1, 1, n, dfs_id[ha], dfs_id[a], v);
a = fa[ha];
}
}
}
int query_lct(int a, int b){
int ans = 0;
int ha, hb;
while(1){
ha = head[a];
hb = head[b];
if(ha == hb){
a = dfs_id[a];
b = dfs_id[b];
if(a > b) swap(a, b);
ans += query(1, 1, n, a, b);
break;
}else{
if(dep[ha] < dep[hb]){
swap(a, b);
swap(ha, hb);
}
ans += query(1, 1, n, dfs_id[ha], dfs_id[a]);
a = fa[ha];
}
}
return ans;
}
int main(){
scanf("%d", &n);
for(int i = 2; i <= n; ++i){
scanf("%d",&a);
++a;
edges[a].push_back(i);
fa[i] = a;
}
build_lct();
for(int i = 0; i < M; ++i){
lazy[i] = -1;
}
scanf("%d", &m);
while(m--){
scanf("%s%d", op, &x);
++x;
if(*op == 'i'){
printf("%d\n", dep[x] - query_lct(1, x));
modify_lct(1, x, 1);
}else{
printf("%d\n", query(1, 1, n, subtree_begin[x], subtree_end[x]));
modify(1, 1, n, subtree_begin[x], subtree_end[x], 0);
}
}
return 0;
}
---- suffer now and live the rest of your life as a champion ----