Heavy-light Decompositions Problem Code: HLDOTSSubmit

All submissions for this problem are available.

Heavy-light decomposition of a tree is a powerful tool that often helps in the most difficult tree data structure problems.

Heavy-light decomposition is to be built on a rooted tree. In this problem, the node with the number 1 should be considered the root of a tree. Heavy light decomposition is a colouring of edges of the tree. Each edge is either heavy or light. For each non leaf node (node having degree greater than 1), from all the edges emanating from it into the subtree rooted at this vertex should have exactly one heavy edge.

The heavy-light decomposition is called correct, if you can reach any node from the root node by using no more that ⌊ log2 N ⌋ light edges, where N is the number of nodes in the tree.

Given a tree, calculate the number of its' correct heavy-light decompositions. As answer could be very large, please print it modulo 19101995.

Input

There is exactly one test case.

The first line of input consists of a single integer N, denoting the number of the nodes in the tree.

Each of the following N - 1 lines contains a pair of integers, denoting the numbers of the nodes that are connected with an edge. The nodes are enumerated by positive integers in the range [1; N].

Output

Output the number of correct heavy-light decompositions of the given tree. Since this number can be huge, please output it modulo 19101995.

Constraints

  • (Subtask 1): 1 ≤ N ≤ 20 - 21 point.
  • (Subtask 2): 1 ≤ N ≤ 1000 - 34 points.
  • (Subtask 3): 1 ≤ N ≤ 100000 - 45 points.

Example

Input:
7
1 2
3 1
3 4
3 5
2 6
2 7 Output:
8

Explanation

Example case 1. Input is a complete binary tree. It consists of 7 nodes, therefore you can't have more than ⌊log2 7⌋ = ⌊(2.80735492206)⌋ = 2 light edges on the path from the root node to any other one. But the tree's height is 2, so you can choose the decomposition in any way you like. All the decompositions will be correct ones. There are three nodes that has outgoing edges from them (in the direction opposite to the root's one), their numbers are 1, 2 and 3. Each of them has 2 outgoing edges from which you can colour exactly one of them heavy, so overall you'll have 2 * 2 * 2 = 8 options of creating the correct heavy-light decompositions.

 
 
题意:求从根到任意节点经过的轻链的个数不超过$log_2n$的轻重链划分的方案数。
一个树dp。
由于模数是一个合数,所以不能直接用快速幂求逆元,可以用改用前缀后缀和做。
f是前缀和,g是后缀和。
注意没有儿子(叶子)和只有一个儿子的特殊情况。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const long long maxn=1e5+10,mod=19101995;
long long n,f[maxn][20],g[maxn][20],ans[maxn][20],fa[maxn],sz,fr[2*maxn]; long long aa;char cc;
long long read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
} long long fir[maxn],nxt[2*maxn],to[2*maxn],e=0;
void add(long long x,long long y) {
to[++e]=y;nxt[e]=fir[x];fir[x]=e;
to[++e]=x;nxt[e]=fir[y];fir[y]=e;
} long long rs;
long long qp(long long x,long long k) {
rs=1;if(x<=1) return x;
while(k) {
if(k&1) (rs*=x)%=mod;
x=x*x%mod;k>>=1;
}
return rs;
} void dfs(long long pos) {
long long z,tt=0,tot;
for(long long y=fir[pos];y;y=nxt[y]) {
if((z=to[y])==fa[pos]) continue;
fa[z]=pos; dfs(z);
}
for(long long i=0;i<=sz;++i) f[0][i]=1ll;
for(long long y=fir[pos];y;fr[nxt[y]]=y,y=nxt[y]) {
if((z=to[y])==fa[pos]) continue; tt++;
for(long long i=0;i<=sz;++i) (f[tt][i]=f[tt-1][i]*ans[z][i])%=mod;
}
tot=tt;
for(long long i=0;i<=sz;++i) g[tt][i]=1ll;
fr[fir[pos]]=0;
for(long long y=fr[0];y;y=fr[y]) {
if((z=to[y])==fa[pos]) continue; tt--;
for(long long i=0;i<=sz;++i) (g[tt][i]=g[tt+1][i]*ans[z][i])%=mod;
}
if(tot>1) for(long long y=fir[pos];y;y=nxt[y]) {
if((z=to[y])==fa[pos]) continue; tt++;
for(long long i=1;i<=sz;++i) (ans[pos][i]+=f[tt-1][i-1]*g[tt][i-1]%mod*ans[z][i])%=mod;
}
else if(!tot)for(long long i=0;i<=sz;++i) ans[pos][i]=1;
else {
if(to[fr[0]]==fa[pos]) fr[0]=fr[fr[0]];
for(long long i=0;i<=sz;++i) ans[pos][i]=ans[to[fr[0]]][i];
}
} int main() {
n=read();long long x,y;
sz=(long long)((double)log(n)/(double)log(2)+1e-8);
for(long long i=1;i<n;++i) {
x=read();y=read();
add(x,y);
}
dfs(1);
printf("%lld",ans[1][sz]);
return 0;
}
/*
7
1 2
3 2
4 3
5 1
6 2
7 3 right answer:
6
*/

  

对拍的rand:

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<ctime>
using namespace std;
const int maxn=15;
int n; int main() {
srand((unsigned)time(NULL));
n=rand()%maxn+2;int x;
printf("%d\n1 2\n",n);
for(int i=3;i<=n;++i) {
x=rand()%(i-1)+1;
printf("%d %d\n",i,x);
}
return 0;
}

  

codechef Heavy-light Decompositions的更多相关文章

  1. Heavy Light Decomposition

    Note 1.DFS1 mark all the depth mark fathers mark the heavy/light children mark the size of each subt ...

  2. 树链剖分I 原理

    树链剖分(Heavy Light Decomposition, HLD)是一种将对[树上两点间的路径]上[边或点]的[修改与查询]转化到[序列]上来处理的方法. 目的:将树的边或点转化到一个线性结构( ...

  3. ACM/ICPC 之 拓扑排序-反向(POJ3687)

    难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重 ...

  4. poj1013

    题目大意:假造的银币 Sally Jones有一些游客给的银币,但是只有11枚是真正的银币(有一枚是假的),从颜色和大小是无法区分真比还是假币的,但是它的重量和真币是不同的,Sally Jones它是 ...

  5. Java8 in action(1) 通过行为参数化传递代码--lambda代替策略模式

    [TOC] 猪脚:以下内容参考<Java 8 in Action> 需求 果农需要筛选苹果,可能想要绿色的,也可能想要红色的,可能想要大苹果(>150g),也可能需要红的大苹果.基于 ...

  6. TCP与UDP区别小结

    TCP(Transmission Control Protocol):传输控制协议 UDP(User Datagram Protocol):用户数据报协议       主要从连接性(Connectiv ...

  7. POJ1013 称硬币

    题目链接:http://poj.org/problem?id=1013 题目大意 有12枚硬币.其中有11枚真币和1枚假币.假币和真币重量不同,但不知道假币比真币轻还是重.现在,用一架天平称了这些币三 ...

  8. 神奇的树上启发式合并 (dsu on tree)

    参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...

  9. HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树

    题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...

随机推荐

  1. combobox 的onLoadSuccess执行两次解决办法和 取值赋值

    加红色字部分 jsp <input class="easyui-combobox" id="keshi" name="keshi" v ...

  2. Eclipse使用过程的常见问题:

     3-1  "Failed to load the JNI shared library"               -jdk 与eclipse位数不一致出现的问题 解决方法: ...

  3. valueStack(值栈)

    值栈 值栈(ValueStack)就是 OGNL 表达式存取数据的地方.在一个值栈中,封装了一次请求所需要的所有数据. 在使用 Struts2 的项目中,Struts2 会为每个请求创建一个新的值栈, ...

  4. [Day2] Nginx静态文件

    ​上一节我们介绍了nginx的三个使用场景和一些配置语法参数,今天我们就用一章的内容来介绍一下Nginx作为静态资源服务器的配置和常见问题. 一. 简单的静态服务器 ​话不多说,直接上配置代码. se ...

  5. shiro+jwt+springboot理解

    转自 https://www.cnblogs.com/fengli9998/p/6676783.html https://www.jianshu.com/p/0366a1675bb6 https:// ...

  6. python时间处理,datetime中的strftime/strptime

    python中datetime模块非常好用,提供了日期格式和字符串格式相互转化的函数strftime/strptime 1.由日期格式转化为字符串格式的函数为: datetime.datetime.s ...

  7. bzoj 1179 [Apio2009]Atm——SCC缩点+spfa

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1179 显然SCC缩点. 然后准备倒着拓扑序推到st,结果WA. 听TJ说dj求最长路会发生不 ...

  8. VSCode 配置阿里云CentOS 7.6 远程开发

    配置步骤 一.windows 10 开发机配置 windows 10 1809后支持ssh命令 1.生成ssh密钥.使用以下命令,先生成本地公钥和私钥ssh-keygen -t rsa -b 4096 ...

  9. python统计一个文本中重复行数的方法

    python统计一个文本中重复行数的方法 这篇文章主要介绍了python统计一个文本中重复行数的方法,涉及针对Python中dict对象的使用及相关本文的操作,具有一定的借鉴价值,需要的朋友可以参考下 ...

  10. 【arc077f】AtCoder Regular Contest 074 F - Lotus Leaves

    题意 给定一个n*m的池塘,每个格子上可能有叶子. 从一个叶子出发,可以跳到相同行或相同列的叶子. 问至少去掉多少叶子,使得起点不能到达终点. \(n,m<=100\) 解法 很显然的最小割模型 ...