poj 3321 Apple Tree

原创 2015年11月21日 14:49:54
要是你想做这个题,你首先要知道一个基(shen)本(qi)的性质:树上的每个子树的dfs序都是连续的
一个很显然的性质(知道了就不会忘了)

然后就可以做这个题啦

区间和用树状数组简单的维护一下就好

我的代码维护的是这个子树的空节点(就是没有苹果的节点),那么有苹果的节点数目就是(子树大小)-(空节点数)

(轮这个题的坑
(1. 数据范围绝对不止1e5,我开到了1e6才能过,而且数组开小了返回的还是TLE。。。。迷
(2. 这个题卡vector,用vector的可以改用一发其他的姿势了(比如前向星


然后然后感觉其他的也没有什么难想的地方


那么就这样



#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn = 1123456;

struct Edge{
    int next,to;
}edge[maxn];

int head[maxn],top;

void init(int n){
    memset(head,-1,sizeof(head));
    top=0;
}

void Link(int st,int ed){
    edge[top].to=ed;
    edge[top].next=head[st];
    head[st]=top++;
}

int siz[maxn],sid[maxn];
int _cnt;

void dfs(int st,int fa){
    siz[st]=1,sid[st]=_cnt++;
    for(int i = head[st];~i;i=edge[i].next){
        int x = edge[i].to;
        if(x!=fa){
            dfs(x,st);
            siz[st]+=siz[x];
        }
    }
}

void tinit(){
    _cnt=1;
    dfs(1,0);
}

int sum[maxn],hav[maxn];

void bitinit(){
    memset(sum,0,sizeof(sum));
    memset(hav,0,sizeof(hav));
}

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

void add(int x,int d,int n){
    while(x<=n){
        sum[x]+=d;
        x+=lowbit(x);
    }
}

int que(int x){
    int ret = 0;
    while(x>0){
        ret += sum[x];
        x-=lowbit(x);
    }
    return ret;
}

void update(int x,int n){
    int d = hav[x]?-1:1;
    hav[x] = d==1;
    add(sid[x],d,n);
}

int query(int x){
    int val = que(siz[x]+sid[x]-1);
    val-=que(sid[x]-1);
    return siz[x]-val;
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        int x,y;
        init(n);
        for(int i=1;i<n;i++){
            scanf("%d %d",&x,&y);
            Link(x,y);
            Link(y,x);
        }
        tinit();
        bitinit();
//        for(int i=1;i<=n;i++)
//            printf(i<n?"%d ":"%d\n",sid[i]);
//        for(int i=1;i<=n;i++)
//            printf(i<n?"%d ":"%d\n",siz[i]);
        int m;
        char ord[10];
        scanf("%d",&m);
        while(m--){
            scanf("%s %d",ord,&x);
            if(ord[0]=='C')
                update(x,n);
            else
                printf("%d\n",query(x));
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

【树状数组--dfs序转化】poj3321 Apple Tree

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29822   Accepted: 8881...

poj 3321 Apple Tree(dfs染色+树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27212   Ac...

POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25904   Accepted: 7682...

POJ 3321 Apple Tree 树状数组 树到数组的映射 区间求和

我觉得是一道很不错的题目了,自己写出来的感觉真是不错。。。(虽然是看了别人的题解),总之写完之后我又回过头思考了一下,发现大概的思考路径可能是这样:         这道题目的重点就是在于对于操作Q的...

poj3321---Apple Tree

题目大意: 给你一颗苹果树,树的主干设为1,每一个分支设为一个数,一直到N,代表这颗苹果树。每个分支上面只能最多有一个苹果,也就是一个枝子上面不可能有两个苹果,另外注意一点,不要把苹果树想象成二叉树...

poj 3321Apple Tree 树状数组

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19178   Ac...

poj 3321 Apple tree 解题报告

翻译(复制的):卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果。卡卡很喜欢苹果。树上有N个节点,卡卡给他们编号1到N,根的编号永远是1.每个节点上最多结一个苹果。卡卡想要了解某一个子树上一共结了多少...

POJ3321:Apple Tree(树状数组)

Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will gr...

Apple Tree_poj3321_树状数组&dfs

Description There is an apple tree outside of kaka'shouse. Every autumn, a lot of apples will grow i...
  • jpwang8
  • jpwang8
  • 2016年05月23日 20:54
  • 309

poj 3321 Apple Tree( 树状数组 )

题意 : 有一颗N(N对该果树有两种操作:C x : 更新果树,若x叉处有苹果,则摘下;若没有,则长出一个新的。Q x : 统计子树x上的苹果数量(包括x)这题的关键就是怎样将树中的节点映射到树状数组...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 3321 Apple Tree
举报原因:
原因补充:

(最多只允许输入30个字)