[BZOJ 4196][Noi2015]软件包管理器

来源:互联网 发布:如何练出完美胸肌知乎 编辑:程序博客网 时间:2024/05/17 08:04

树链剖分

注意最好不要用0作为节点, 重儿子会挂


还有尽可能的开大数组


相信树剖的效率



#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 200010using namespace std;int n;int h[maxn], cnt;struct Edge{int to, next;}edge[maxn];void add(int u, int v){cnt ++;edge[cnt].to = v;edge[cnt].next = h[u];h[u] = cnt;}int size[maxn], pos[maxn], son[maxn], top[maxn], dfs_clock, dep[maxn];int L[maxn], R[maxn], fa[maxn];void dfs1(int u){size[u] = 1;dep[u] = dep[fa[u]] + 1;for(int i = h[u]; i; i = edge[i].next){int v = edge[i].to;fa[v] = u;dfs1(v);size[u] += size[v];if(size[v] > size[son[u]])    son[u] = v;}}void dfs2(int u, int tp){top[u] = tp;pos[u] = ++ dfs_clock;L[u] = dfs_clock;if(son[u])dfs2(son[u], tp);for(int i = h[u]; i; i = edge[i].next){int v = edge[i].to;if(v == son[u])continue;dfs2(v, v);}R[u] = dfs_clock;}struct Node{int l, r, lazy, sum;}t[maxn << 2];struct Segment{#define lc id << 1#define rc id << 1 | 1void build(int id, int l, int r){t[id].l = l, t[id].r = r;if(l == r)return;int mid = l + r >> 1;build(lc, l, mid);build(rc, mid + 1, r);}void pushdown(int id){if(t[id].lazy == 0)return;t[lc].lazy = t[rc].lazy = t[id].lazy;if(t[id].lazy < 0)t[id].sum = 0;else{if(id == 1)t[id].sum = n;else{                int mid = t[id >> 1].l + t[id >> 1].r >> 1;if(t[id].r == mid)t[id].sum = mid - t[id].l + 1;else t[id].sum = t[id].r - mid;}}t[id].lazy = 0;}void Modify(int id, int l, int r, int val){pushdown(id);if(t[id].l == l && t[id].r == r){t[id].lazy = val;if(t[id].lazy > 0)t[id].sum = r - l + 1;else t[id].sum = 0;return;  }int mid = t[id].l + t[id].r >> 1;if(r <= mid){pushdown(rc);Modify(lc, l, r, val);}else if(l > mid){pushdown(lc);Modify(rc, l, r, val);}else{Modify(lc, l, mid, val);Modify(rc, mid + 1, r, val);}t[id].sum = t[lc].sum + t[rc].sum;}int ask(int id, int l, int r){pushdown(id);if(t[id].l == l && t[id].r == r)return t[id].sum;        int mid = t[id].l + t[id].r >> 1;if(r <= mid)return ask(lc, l, r);else if(l > mid)return ask(rc, l, r);else return ask(lc, l, mid) + ask(rc, mid + 1, r);}#undef lc#undef rc}T;int Getans(int u, int val){int pd = T.ask(1, pos[u], pos[u]);if(val < 0 && pd == 0)    return 0;if(val > 0 && pd == 1)    return 0;int ans = 0;if(val > 0){ans = dep[u];        while(~ u){ans -= T.ask(1, pos[top[u]], pos[u]);T.Modify(1, pos[top[u]], pos[u], 1);u = fa[top[u]];}}else{ans = T.ask(1, L[u], R[u]);T.Modify(1, L[u], R[u], -1);}return ans;}int main(){scanf("%d", &n);int u;for(int i = 2; i <= n; i ++){scanf("%d", &u);u ++;add(u, i);}dfs1(1);dfs2(1, 1);T.build(1, 1, n);fa[1] = -1;int test;char cmd[10];scanf("%d", &test);while(test --){scanf("%s%d", cmd, &u);u ++;printf("%d\n", Getans(u, cmd[0] == 'i' ? 1 : -1));}return 0;}


0 0
原创粉丝点击