CF#468 div2 D. Peculiar apple-tree(思维)

书史足自悦,安用勤与劬。这篇文章主要讲述CF#468 div2 D. Peculiar apple-tree(思维)相关的知识,希望能为你提供帮助。
题干:
In Arcadys garden there grows a peculiar apple-tree that fruits one time per year. Its peculiarity can be explained in following way: there are  n  inflorescences, numbered from  1  to  n. Inflorescence number  1  is situated near base of tree and any other inflorescence with number  i  (i?> ?1) is situated at the top of branch, which bottom is  pi-th inflorescence and  pi?< ?i.
Once tree starts fruiting, there appears exactly one apple in each inflorescence. The same moment as apples appear, they start to roll down along branches to the very base of tree. Each second all apples, except ones in first inflorescence simultaneously roll down one branch closer to tree base, e.g. apple in  a-th inflorescence gets to  pa-th inflorescence. Apples that end up in first inflorescence are gathered by Arcady in exactly the same moment. Second peculiarity of this tree is that once two apples are in same inflorescence they  annihilate. This happens with each pair of apples, e.g. if there are  5  apples in same inflorescence in same time, only one will not be annihilated and if there are  8  apples, all apples will be annihilated. Thus, there can be no more than one apple in each inflorescence in each moment of time.
Help Arcady with counting number of apples he will be able to collect from first inflorescence during one harvest.
Input
First line of input contains single integer number  n  (2?≤?n?≤?100?000)   — number of inflorescences.
Second line of input contains sequence of  n?-?1  integer numbers  p2,?p3,?...,?pn  (1?≤?pi?< ?i), where  pi  is number of inflorescence into which the apple from  i-th inflorescence rolls down.
Output
Single line of output should contain one integer number: amount of apples that Arcady will be able to collect from first inflorescence during one harvest.
Examples
Input

3
1 1

Output
1

Input
5
1 2 2 2

Output
3

Input
18
1 1 1 4 4 3 2 2 2 10 8 9 9 9 10 10 4

Output
4

Note
In first example Arcady will be able to collect only one apple, initially situated in  1st inflorescence. In next second apples from  2nd and  3rd inflorescences will roll down and annihilate, and Arcady wont be able to collect them.
In the second example Arcady will be able to collect 3 apples. First one is one initially situated in first inflorescence. In a second apple from  2nd inflorescence will roll down to  1st (Arcady will collect it) and apples from  3rd,  4th,  5th inflorescences will roll down to  2nd. Two of them will annihilate and one not annihilated will roll down from  2-nd inflorescence to  1st one in the next second and Arcady will collect it.
题目大意:
      一颗苹果树,每个开花的位置都会结一个苹果,花的位置序列已经给出(n各节点则输入n-1个数,因为默认1号节点在深度为0),输入的顺序即是树的节点的标号顺序,输入的值代表这个节点的父亲节点是的序号,结果子之后,苹果会向下落、序列1的位置在最下面。只有落到序列1位置的苹果可以摘,苹果下落时有两种规则
1、两个苹果相撞就会消失
2、苹果下一次出现的位置为当前花序对应的pi值
 
问 一个能摘到多少个苹果
解题报告:
      这个题的关键是分析出,最后摘到苹果的数量就是每一层的果子的奇偶数,而与   和上一层的节点的连接关系无关。   即假设:第二层有两个节点,第三层有三个节点,那么,第三层的节点无论怎么与第二层的连接,你会发现最终落到第一层的结果都是一样的(因为这一层的在某一个时间内同时落下,与第二层本身有几个果子,第四层本身有多少果子都没有关系,所以相当于认为这棵树上只有第三层有果子,来分析到第一层的情况)。
AC代码:(直接维护每一层的果子数)
#include< bits/stdc++.h>

using namespace std;
int sum[100000 + 5];
int dep[100000 + 5];
int root;
int ans;
int main()

int n;
int maxx = 0;
cin> > n;
dep[1]=1; sum[1] = 1;
for(int i = 2; i< =n; i++)
scanf("%d",& root);
dep[i] =dep[root] + 1;
maxx = max(maxx,dep[i] );
sum[dep[i] ] +=1;

//printf("maxx = %d\\n",maxx);
for(int i = 1; i< =maxx; i++)
ans +=sum[i]%2;

cout< < ans< < endl;

return 0 ;

AC代码:(可以用搜索树从下到上跑一边,其本质是一样的都是要统计每一层果子数)
#include < bits/stdc++.h>
#define MOD 10000
#define INF 0x3f3f3f3f
#define bug cout < < "bug" < < endl


using namespace std;
typedef long long ll;

const int MAX_N=1e5+5;
int n,m;
vector < int> edge[MAX_N];
int cnt[MAX_N],depth[MAX_N];

void dfs1(int v,int dep)
depth[v]=dep;
for(int i=0; i< (int)edge[v].size(); i++)
dfs1(edge[v][i],dep+1);

return ;

int main(void)
int n,par;
cin > > n;
for(int i=2; i< =n; ++i)
scanf("%d",& par);
edge[par].push_back(i);

int ans=0;
dfs1(1,0);
for(int i=1; i< =n; i++)cnt[depth[i]]++;
for(int i=0; i< =n; i++)
if(cnt[i]& 1)ans++;

cout < < ans < < endl;

总结:思维题还是要先分析一下情况在动笔,说不定题目很简单,但是想复杂了 !可以找几个样例找找规律。
【CF#468 div2 D. Peculiar apple-tree(思维)】


    推荐阅读