zoukankan      html  css  js  c++  java
  • poj3321 Apple Tree ****

    /*
      看了网上的代码。。再自己写了一个。。。
    ( 网上很多代码都是默认输入的数据u是v的父节点。。  也能AC。。  但不严谨。。)
    【转】
    思路:树状数组。这道题重点怎么建立树到树状数组的映射关系:利用dfs遍历树,
    对每个节点进行两次编号,第一次搜到第i个节点时的深度dep,
    为这个节点管辖区间的上限low[i](也为这个节点的下标),然后搜这个节点的子节点,
    最后搜回来后的深度dep,为这个节点管辖区间的下限high[i]。接下来就是树状数组部分了。
    */

    /*

    * 3321
    * 邻接表建树+树状数组
    *
    */
    #include
    <cstdio>
    using namespace std;

    const int MAXN = 100000 + 5;
    struct SData{ //节点
    int value;
    SData
    *next;
    };
    SData edgehead[MAXN];
    //邻接表

    bool vis[MAXN] = {};
    int n, m, u, v, dep = 0, s; //n,m,u,v同题意。。 s为命令里的数字
    int low[MAXN], high[MAXN]; //上、下限
    bool apple[MAXN]; //是否有苹果
    int c[MAXN] = {}; //树状数组
    char cmd; //命令

    //dfs
    void dfs(int x){
    low[x]
    = ++dep;
    vis[x]
    = 1;

    SData
    *p = edgehead[x].next;
    while(p){
    if(!vis[p->value])
    dfs(p
    ->value);
    p
    = p->next;
    }
    high[x]
    = dep;
    }

    int lowbit(int x){
    return x & (-x);
    }

    void update(int x, int delta){
    for(int i=x; i<=n; i+=lowbit(i)){
    c[i]
    += delta;
    }
    }

    int sum(int x){
    int ans = 0;
    for(int i=x; i>0; i-=lowbit(i)){
    ans
    += c[i];
    }
    return ans;
    }

    int main(){
    scanf(
    "%d", &n);
    for(int i=1; i<n; i++){
    scanf(
    "%d %d", &u, &v);

    //邻接表建树
    SData *p = new SData;
    p
    ->value = v;
    p
    ->next = edgehead[u].next;
    edgehead[u].next
    = p;

    SData
    *q = new SData; //注意反过来也要建。(若默认u是v的父节点,则可省略)
    q->value = u;
    q
    ->next = edgehead[v].next;
    edgehead[v].next
    = q;
    }
    dfs(
    1);

    //起始时刻每个节点都有苹果
    for(int i=1; i<=n; i++){
    apple[i]
    = 1;
    update(i,
    1);
    }

    //命令
    scanf("%d", &m);

    for(int i=0; i<m; i++){
    scanf(
    "%c", &cmd);
    scanf(
    "%c %d", &cmd, &s);

    if(cmd == 'C'){
    int delta;
    apple[s]
    = !apple[s];
    delta
    = (apple[s] == 1 ? 1 : -1);
    update(low[s], delta);
    //low[s]也代表s在数组中的位置
    }
    else if(cmd == 'Q'){
    int ans = sum(high[s]) - sum(low[s]-1);
    printf(
    "%d\n", ans);
    }
    }

    return 0;
    }

  • 相关阅读:
    以最少的循环把两个数组里面的相同结果输出来
    解决PL/SQL Developer连接数据库时出现 “ORA-12541:TNS:无监听程序”错误
    AOP中Advice执行两遍的原因
    Java注释@interface的用法
    Spring进阶教程之在ApplicationContext初始化完成后重定义Bean
    Java的注解机制——Spring自动装配的实现原理
    基数排序简单Java实现
    jQuery的选择器中的通配符
    SEO 网站页面SEO优化之页面title标题优化
    IntelliJ IDEA 中文乱码解决
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2103414.html
Copyright © 2011-2022 走看看