題目大意:有一棵樹,兩個修改
$install\;x:$把根節點到$x$軟體路徑上的值全部變為$1$,並輸出修改的節點個數
$uninstall\;x:$把$x$以及它的子樹的值變為$0$,並輸出修改的節點個數
題解:樹鏈剖分,比較一下修改前後值的變化,即為答案
卡點:1.邊忘記開兩倍
c++ code:
#include #define maxn 100010using namespace std;
int n, m;
int head[maxn], cnt;
struct edge e[maxn << 1];
void add(int a, int b) ; head[a] = cnt;
}int dep[maxn], sz[maxn], fa[maxn];
int dfn[maxn], son[maxn], top[maxn], idx;
void dfs1(int rt) }}
void dfs2(int rt) }}
int v[maxn << 2];
void add(int rt, int l, int r, int l, int r, int op)
if (v[rt] == r - l + 1)
int mid = l + r >> 1;
if (l <= mid) add(rt << 1, l, mid, l, r, op);
if (r > mid) add(rt << 1 | 1, mid + 1, r, l, r, op);
v[rt] = v[rt << 1] + v[rt << 1 | 1];
}int ask(int rt, int l, int r, int l, int r)
if (v[rt] == 0) v[rt << 1] = v[rt << 1 | 1] = 0;
int mid = l + r >> 1, ans = 0;
if (l <= mid) ans = ask(rt << 1, l, mid, l, r);
if (r > mid) ans += ask(rt << 1 | 1, mid + 1, r, l, r);
return ans;
}inline void swap(int &a, int &b)
void modify(int x, int y, int num)
if (dep[x] > dep[y]) swap(x, y);
add(1, 1, n, dfn[x], dfn[y], num);
}int query(int x, int y)
if (dep[x] > dep[y]) swap(x, y);
ans += ask(1, 1, n, dfn[x], dfn[y]);
return ans;
}int root = 1;
int main()
dep[top[root] = root] = 1;
dfs1(root);
dfs2(root);
scanf("%d", &m);
while (m --> 0) else
} return 0;
}
bzoj4196 NOI2015 軟體包管理器
time limit 10 sec memory limit 512 mb submit 1168 solved 672 你決定設計你自己的軟體包管理器。不可避免地,你要解決軟體包之間的依賴問題。如果軟體包a依賴軟體包b,那麼安裝軟體包a以前,必須先安裝軟體包b。同時,如果想要解除安裝軟體包b,則必...
bzoj 4196 Noi2015 軟體包管理器
你決定設計你自己的軟體包管理器。不可避免地,你要解決軟體包之間的依賴問題。如果軟體包a依賴軟體包b,那麼安裝軟體包a以前,必須先安裝軟體包b。同時,如果想要解除安裝軟體包b,則必須解除安裝軟體包a。現在你已經獲得了所有的軟體包之間的依賴關係。而且,由於你之前的工作,除0號軟體包以外,在你的管理器當中...
bzoj4196 noi2015 軟體包管理器
題目描述 你決定設計你自己的軟體包管理器。不可避免地,你要解決軟體包之間的依賴問題。如果軟體包a依賴軟體包b,那麼安裝軟體包a以前,必須先安裝軟體包b。同時,如果想要解除安裝軟體包b,則必須解除安裝軟體包a。現在你已經獲得了所有的軟體包之間的依賴關係。而且,由於你之前的工作,除0號軟體包以外,在你的...