bzoj 3696 化合物 解题报告
2017-07-19 21:17
288 查看
Description
首长NOI惨跪,于是去念文化课了。现在,他面对一道化学题。这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏。这个游戏很蛋疼,我相信你们也没有兴趣听。
由于这个游戏涉及博弈论,因此化竞的同学就要求首长求一个类似SG函数的值。
他们手中有一种非常神奇的化合物,它的分子由N个原子组成(不要在意一个原子可能和及其多个原子成键这个细节)。这个分子构成一个树结构,1号分子为根。 若两个原子i、j到它们的最近公共祖先的距离分别是Li和Lj,定义它们的Aij值为:
Aij=Li xor Lj
题目要求对于每一个k(k∈N),求出两两A值为k的原子对个数。
Input
第一行一个整数N。接下来N-1行,每行一个整数p,第新亍的整数表示第i个原子的父亲为p。
Output
从K=0开始,第k+1行输出两两A值为K的原子对个数,输出到第一个不为零的数为止。Sample Input
31
1
Sample Output
12
HINT
【数据规模与约定】用h表示树结构分子的最大深度。
N<=10^5,H<=500
思路
枚举每个点暴力。。。???还真是奇特的数据。。。代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> using namespace std; const int N=100000+5; const int M=500+5; int n,num,a [M],ans[M],head ,deep ,maxn=M; struct edge { int v,next; }; edge ed ; void build(int u,int v) { ed[++num].v=v; ed[num].next=head[u]; head[u]=num; } void dfs(int x) { a[x][0]=1; for (int i=head[x];i;i=ed[i].next) { dfs(ed[i].v); for (int j=0;j<=deep[x];j++) for (int k=0;k<=deep[ed[i].v];k++) ans[j^(k+1)]+=a[x][j]*a[ed[i].v][k]; deep[x]=max(deep[x],deep[ed[i].v]+1); for (int j=0;j<=deep[ed[i].v];j++) a[x][j+1]+=a[ed[i].v][j]; } } int main() { scanf("%d",&n); for (int i=2;i<=n;i++) { int x; scanf("%d",&x); build(x,i); } dfs(1); while(maxn>0) {maxn--;if (ans[maxn]) break;} for (int i=0;i<=maxn;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- BZOJ 2007 对偶图 解题报告
- BZOJ 3288 Mato矩阵 解题报告
- [bzoj2861] 双向边定向为单向边 解题报告
- bzoj 4318 期望DP 解题报告
- BZOJ 1131 [POI 2008] 解题报告
- [bzoj3282]tree 解题报告
- BZOJ 4341 [CF253 Printer] 解题报告
- [bzoj4621] Tc605 解题报告
- [bzoj1001]狼抓兔子解题报告(最大流最小割定理)
- bzoj 1013: [JSOI2008]球形空间产生器sphere 解题报告
- BZOJ 1093 [ZJOI 2007] Tarjan+DAG拓扑排序DP 解题报告
- [BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)
- bzoj 1028 麻将 模拟 解题报告
- BZOJ 1475 最小割 解题报告
- [bzoj3956]Count 解题报告
- [树形DP 暴力] BZOJ 3696 化合物
- BZOJ 2144 LCA 解题报告
- bzoj 1631: [Usaco2007 Feb]Cow Party 解题报告
- bzoj 2190 仪仗队 解题报告 素数筛
- [bzoj3462]dzy loves math II 解题报告