【题目描述】

  首长NOI惨跪,于是去念文化课了。现在,他面对一道化学题。

  这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏,这个游戏很蛋疼,我相信你们也没有兴趣听。

  由于这个游戏涉及博弈论,因此化竞的同学就要求首长求一个类似SG函数的值。

  他们手中有一种非常神奇的化合物,它的分子由N个原子组成(不要在意一个原子可能和及其多个原子成键这个细节)。这个分子构成了一个树结构,1号分子为根。

  若两个原子i、j到它们的最近公共祖先的距离分别是li和lj,定义它们的Aij值为:

Aij = li xor lj

  题目要求对于每一个k(k∈N),求出两两A值为k的原子对个数。

【输入格式】

  第一行一个整数N。

  接下来N-1行,每行一个整数p,第i行的整数表示第i个原子的父亲为p。

【输出格式】

  从k=0开始,第k+1行输出两两A值为k的原子对个数,输出到最后一个不为零的数为止。

【样例输入】

3

1

1

【样例输出】

1

2

【数据范围】用h表示树结构分子的最大深度。

  40%:N<=1000,h<=30

  70%:N<=3000,h<=100

  100%:N<=100000,h<=500

Solution

  暴力70分啊。。。。。。这么良心。

  100%:类似树分治的做法,只不过每次只能选指定的非叶子结点。

  考虑子树中经过根的路径对答案造成的影响,记f[x][j]表示以x结点为根的子树,与x结点距离为j的结点数。显然可以通过dfs转移。影响分两种:

  1.以x为起点的链。ans[j]+=f[x][j];

  2.端点在不同子树内。比如下面这组数据:

    N=6,fa[]={0,1,1,2,2,2}

  有f[2]={1,3},f[3]={1}.

  两个数组乘起来,什么事都解决了。

  其实这叫母函数= =

  f[2]=x+3x^2,f[3]=x

  本来f[2]*f[3]=x^2+3x^3

  但是这是异或,所以指数上不能相加而是异或,于是f[2]*f[3]=1+3x^3

  如果有多个子树,就两两暴力乘吧。异或这种东西不知道还是不要玩为妙。

  

  然后这还只是暴力,标程把乘法的O(n^2)用fwt降成了O(nlogn),真是寂寞如雪= =

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<algorithm>
int fa[];
int main()
{
freopen("che.in","w",stdout);
srand(time());
int n=;printf("%d\n",n);
for(int i=;i<=;i++)printf("%d ",rand()%(i-));
for(int i=;i<=n;i++)printf("%d ",rand()%+i-);
}

Data Maker

 #include<cstdio>
#include<cstring>
int fa[],n,dep[],q[],l,r,max,tmp,a[];long long ans[];
struct E{int to,nxt;}e[];
int et,la[];
void add(int x,int y){e[++et]=(E){y,la[x]};la[x]=et;}
int lca(int x)
{
for(;x;x=fa[x])if(a[dep[x]]==x)break;
return x;
}
int main()
{
scanf("%d",&n);int i,j,k;dep[]=;
for(i=;i<=n;i++)scanf("%d",&fa[i]),add(fa[i],i);
for(q[l=r=]=;l<=r;l++)
for(i=la[q[l]];i;i=e[i].nxt)
if(!dep[e[i].to])
dep[q[++r]=e[i].to]=dep[q[l]]+;
for(i=;i<n;i++)
{
memset(a,,sizeof(a));
for(j=i;j;j=fa[j])a[dep[j]]=j;
for(j=i+;j<=n;j++)
{
k=lca(j);
// printf("i=%d j=%d k=%d ans=%d %d\n",i,j,k,(dep[i]-dep[k]),(dep[j]-dep[k]));
ans[tmp=(dep[i]-dep[k])^(dep[j]-dep[k])]++;
if(max<tmp)max=tmp;
}
}
for(k=;k<=max;k++)printf("%lld\n",ans[k]);
}
/*
9
1 1 2 2 2 3 7 7
*/

70%

 #include<cstdio>
#include<cstring>
const int MAXN=,MAXM=;
long long ans[MAXM],tmp2[MAXM];
int fa[MAXN],n,dep[MAXN],q[MAXN],l,r,max,tmp[MAXM],et,la[MAXN],f[MAXN][MAXM],mdep[MAXN];
struct E{int to,nxt;}e[MAXN];
void add(int x,int y){e[++et]=(E){y,la[x]},la[x]=et;}
void mult(int*a,int*b,int&n)
{
memset(tmp2,,sizeof(tmp2));int i,j,c=,t=n;
for(i=;i<=n;i++)if(a[i])
for(j=;j<=n;j++)if(b[j])
tmp2[c=((i+)^(j+))]+=1LL*a[i]*b[j],t<c?t=c:;
for(n=t,i=;i<=n;i++)ans[i]+=tmp2[i];
}
void dfs(int x)
{
bool flag=;int i,j;
for(i=la[x];i;i=e[i].nxt)
{
dfs(e[i].to);
if(mdep[x]<mdep[e[i].to])mdep[x]=mdep[e[i].to];
for(j=;j<=mdep[x];j++)f[x][j+]+=f[e[i].to][j];
}
for(i=la[x];i;i=e[i].nxt)
for(j=e[i].nxt;j;j=e[j].nxt)
mult(f[e[i].to],f[e[j].to],mdep[x]);
f[x][]++;mdep[x]++;
for(i=;i<=mdep[x];i++)ans[i]+=f[x][i];
}
int main()
{
scanf("%d",&n);int i,j,k;dep[]=;
for(i=;i<=n;i++)scanf("%d",&fa[i]),add(fa[i],i);
for(q[l=r=]=;l<=r;l++)
for(i=la[q[l]];i;i=e[i].nxt)
if(!dep[e[i].to])
dep[q[++r]=e[i].to]=dep[q[l]]+;
for(dfs(),max=;!ans[max];max--);
for(k=;k<=max;k++)printf("%lld\n",ans[k]);
}

100%

[FJSC2014]化合物的更多相关文章

  1. [BZOJ3696][FJSC2014]化合物(异或规则下的母函数)

    题目:http://hzwer.com/3708.html 分析: 类似树分治思想,设f[x][i]表示以x为根的子树的所有点中,与x的距离为i的点有多少个,这个可以预处理出来 然后我们考虑每颗子树对 ...

  2. 【BZOJ-3696】化合物 树形DP + 母函数(什么鬼)

    3696: 化合物 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 165  Solved: 85[Submit][Status][Discuss] D ...

  3. RDKIT+postgresql做化合物数据存储与查找

    RDKIT: rdkit的安装与使用,直接conda  instal rdkit,不行的话,使用源码安装,将RDKIT源码下载解压到acaconda的pkg目录下,打开cmd,进入pkg下的 rdki ...

  4. 【BZOJ3696】化合物 树形DP+暴力

    [BZOJ3696]化合物 Description 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题.    这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏.这个游戏很蛋疼 ...

  5. 【bzoj3696】化合物 树形dp

    题目描述 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题.这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏.这个游戏很蛋疼,我相信你们也没有兴趣听.由于这个游戏涉及博弈论, ...

  6. [bzoj3696]化合物_树形dp

    化合物 bzoj-3696 题目大意:给你一棵树,定义两个点i , j之间的A值是(dis[i]-dis[lca(i,j)])xor(dis[j]-dis[lca(i,j)]).对所有的k$\in$[ ...

  7. [Bzoj3696]化合物【暴力+树形Dp】

    Online Judge:Bzoj3696 Label:暴力,树形Dp 题目描述 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题. 这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博 ...

  8. 大视野3562 [SHOI2014]神奇化合物

    http://www.lydsy.com/JudgeOnline/problem.php?id=3562 //Accepted 6020 kb 1012 ms //由于题目的特殊要求:然而,令科学家们 ...

  9. BZOJ3562 : [SHOI2014]神奇化合物

    可以发现,从头到尾有一堆点是始终连在一起的,所以把没被删掉的一开始就有的边都加上后求出每个联通块, 缩完点后我们发现,边数也减少得差不多了,剩下的就直接暴力. #include<cstdio&g ...

随机推荐

  1. 使用反射让Spinner选择同一选项时触发onItemSelected事件

    翻看源码,Spinner判断是否触发onItemSelected,是在它的基类AdapterView里面做的: void checkSelectionChanged() { if ((mSelecte ...

  2. Solr使用初探——SolrJ的使用

    二.SolrJ的使用 SolrJ覆盖了solr的全部功能,下面将自己在实际开发中所使用的程序粘贴出来并适当加以解释,由于本人比较菜,代码书写不是那么的精练,还请见谅. 1.  创建solrserver ...

  3. 完全备份ORACLE数据库 并在另一台电脑上恢复

    由于最近有oracle的项目,需要把数据库在另外一台电脑里面配置一个一样的数据库用来测试开发用,之前是一直使用mssql,只需要附加或者还原就行,但是在oracle里面,就没有这么简单,但是也不难,操 ...

  4. hibernate_validator_01

    1.环境准备(Maven工程) <?xml version="1.0" encoding="UTF-8"?> <project xmlns=& ...

  5. 10.15_SVG可以解决问题吗

    (1)淘宝开放平台. (2)Teiid是一个数据虚拟化系统.Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架.Apache Jackrabbit. (3)SVG:百度百科.SVG.js .Sn ...

  6. LINQ to Entities 查询注意事项

    1> 排序信息丢失 如果在排序操作之后执行了任何其他操作,则不能保证这些附加操作中会保留排序结果.这些操作包括 Select 和 Where 等.另外,采用表达式作为输入参数的 First 和 ...

  7. tq --uboot使用

    - Nand Flash命令- nand info nand erase nand read[.jffs2] addr off size              .jffs代表ECC方式不同 nan ...

  8. 跨域技术-jsonp

    JSONP是JSON with padding 的简写,其有两个部分组成,一个是回调函数,一个是数据,其基本格式如下 function handleResult(result){ alert(resu ...

  9. checkbox在jquery版本1.9 以上用attr不可重复操作的问题【附解决方案】

    最近做个项目,需要重复多次更改checkbox的状态,使用jquery 1.10.2的最新版本时发现,对checkbox的选中状态无法多次选中.测试代码如下: <!DOCTYPE html PU ...

  10. c#面向对象小结

    特点: 1:将复杂的事情简单化. 2:面向对象将以前的过程中的执行者,变成了指挥者. 3:面向对象这种思想是符合现在人们思考习惯的一种思想. 过程和对象在我们的程序中是如何体现的呢?过程其实就是函数: ...