[关闭]
@yang12138 2018-06-21T16:03:16.000000Z 字数 1276 阅读 976

2016年计蒜之道初赛第2题

未分类


题意:
给定个点的一颗树,树上每个点有个权值,边的长度均为,求所有互质的点对的距离的和.
对中等版本,有
对困难版本,有

题解:
对中等版本的数据:
考虑每条边的贡献,树上的每条边都会将树分成两个联通子树,那么对,如果,则会给答案造成的贡献.
考虑莫比乌斯反演,假设表示中点权为的倍数的点的个数,表示中点权为的倍数的点的个数,那么给答案造成的贡献为:


表示的莫比乌斯函数.
可以选一个点将树转换成有根树,记录序,每一条边对应的两个子树中有一个是在序中相邻的一块,可以用线段树辅助求解出.
时间复杂度,空间复杂度.
对困难版本的数据:
同样考虑用莫比乌斯反演来统计每条边的贡献,设是全部点的点权中为的倍数的个数,显然可以被预先处理出来,所以上面的式子可以转化成:

考虑树上动态规划,每个点记录

是一个映射,在这里就是,为了节省空间开销而使用.
维护以上三个结构就可以对两个节点的值进行合并,合并的时候使用启发式合并,也就是将小的暴力拆解拼到大的上面(这里大小指的大小).
总时间复杂度是,空间复杂度是,这里的的因子个数,根据程序运行计算可得.
下面插入一段启发式合并的代码:

  1. void union(Node& l,Node& r){
  2. if(l.size<r.size()) swap(l,r);
  3. l.ans1+=r.ans1;
  4. for(map<int,int>::iterator it=r.mp.begin();it!=r.mp.end();++it){
  5. int t1=l.mp[it->first],t2=t1+it->second;
  6. l.ans2+=mobius[it->first]*(1LL*t1*t1-1LL*t2*t2);
  7. l.mp[it->first]+=it->second;
  8. }
  9. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注