Apple Tree

来源:互联网 发布:商侃的淘宝店 编辑:程序博客网 时间:2024/05/16 10:48

题目连接

  • 题意:
    给n个点(1-n)的树,1为根节点,每个点初始值为1。q次操作:1、C操作:每次给一个标号x,将x节点的值取非  2、Q操作:给x,求x子树的点值之和
  • 分析:
    这个题目关键在于将树上的节点放到一维来处理,这样就可以用树状数组或者线段树来解决了。处理时使用dfs,对每个节点都进行编号。
树状数组:

const int MAXN = 100001;int nxt[MAXN << 1], val[MAXN << 1], head[MAXN], tot = 0;void adj_init(int n){    REP(i, n)        head[i] = -1;    tot = 0;}void adj_ins(int u, int v){    val[tot] = v;    nxt[tot] = head[u];    head[u] = tot++;}int dfs_clock;int lft[MAXN], rht[MAXN];void dfs(int u, int fa){    lft[u] = dfs_clock++;    for (int i = head[u]; ~i; i = nxt[i])    {        if (val[i] != fa)            dfs(val[i], u);    }    rht[u] = dfs_clock - 1;}int tree[MAXN];inline int lowbit(int x){    return x & (-x);}inline void add(int p, int v){    for (; p < MAXN; p += lowbit(p))        tree[p] += v;}inline int sum(int p){    int ret = 0;    for (; p > 0; p -= lowbit(p))        ret += tree[p];    return ret;}int ipt[MAXN];int main(){    int n, q;    while (~RI(n))    {        adj_init(n + 1);        dfs_clock = 1;        CLR(tree, 0);        FE(i, 1, n)            ipt[i] = 1;        REP(i, n - 1)        {            int a, b;            RII(a, b);            adj_ins(a, b);            adj_ins(b, a);        }        dfs(1, -1);        RI(q);        FE(kase, 1, q)        {            char op; int v;            scanf(" %c %d", &op, &v);            int l = lft[v], r = rht[v];            if (op == 'Q')            {                WI(r - l + 1 - sum(r) + sum(l - 1));            }            else            {                int ad = 1;                if (ipt[v] == 0)                    ad = -1;                ipt[v] ^= 1;                add(l, ad);            }        }    }    return 0;}


线段树:
const int MAXN = 100001;int nxt[MAXN << 1], val[MAXN << 1], head[MAXN], tot = 0;void adj_init(int n){    REP(i, n)        head[i] = -1;    tot = 0;}void adj_ins(int u, int v){    val[tot] = v;    nxt[tot] = head[u];    head[u] = tot++;}int dfs_clock;int lft[MAXN], rht[MAXN];void dfs(int u, int fa){    lft[u] = dfs_clock++;    for (int i = head[u]; ~i; i = nxt[i])    {        if (val[i] != fa)            dfs(val[i], u);    }    rht[u] = dfs_clock - 1;}#define lson rt << 1#define rson rt << 1 | 1struct Node{    int l, r, m;    int sum;} nd[MAXN << 2];void pushUP(int rt){    nd[rt].sum = nd[lson].sum + nd[rson].sum;}void build(int l, int r, int rt){    nd[rt].l = l; nd[rt].r = r; nd[rt].m = (l + r) >> 1;    if (l == r)        nd[rt].sum = 1;    else    {        build(l, nd[rt].m, lson);        build(nd[rt].m + 1, r, rson);        pushUP(rt);    }}void add(int p, int v, int rt){    if (nd[rt].l == nd[rt].r)        nd[rt].sum += v;    else    {        if (p <= nd[rt].m)            add(p, v, lson);        else            add(p, v, rson);        pushUP(rt);    }}int query(int L, int R, int rt){    if (L <= nd[rt].l && nd[rt].r <= R)        return nd[rt].sum;    else    {        int ret = 0;        if (L <= nd[rt].m)            ret += query(L, R, lson);        if (R > nd[rt].m)            ret += query(L, R, rson);        return ret;    }}int ipt[MAXN];int main(){    int n, q;    while (~RI(n))    {        adj_init(n + 1);        dfs_clock = 1;        build(1, n, 1);        FE(i, 1, n)            ipt[i] = 1;        REP(i, n - 1)        {            int a, b;            RII(a, b);            adj_ins(a, b);            adj_ins(b, a);        }        dfs(1, -1);        RI(q);        FE(kase, 1, q)        {            char op; int p;            scanf(" %c %d", &op, &p);            int l = lft[p], r = rht[p];            if (op == 'Q')            {                WI(query(l, r, 1));            }            else            {                int ad = -1;                if (ipt[p] == 0)                    ad = 1;                ipt[p] ^= 1;                add(l, ad, 1);            }        }    }    return 0;}


1 0
原创粉丝点击