51nod 1582 n叉树 dp+矩阵乘法
来源:互联网 发布:淘宝蜂蜜店铺推荐 编辑:程序博客网 时间:2024/06/05 09:55
题意
有一棵n叉树,深度是无限的,每个结点有n个儿子。从左到右编号为1到n号儿子,第i号儿子离该结点的距离是di。现在要统计一下距离根结点不超过x的结点有多少个。
数字比较大对 109 + 7 取余后输出。
样例解释:
图中黄色的结点是距离根不超3的。
1≤n≤10^5,0≤x≤10^9,1<=di<=100
分析
注意到di很小,考虑设f[i]表示离根节点距离为i的节点数量。用矩阵快速幂优化转移即可。
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int MOD=1000000007;int n,m,d[100005],mx;struct Matrix{ int a[105][105]; void clear(int n) { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=0; } void unit(int n) { clear(n); for (int i=1;i<=n;i++) a[i][i]=1; }}a;void mul(Matrix &c,Matrix a,Matrix b){ c.clear(mx); for (int i=1;i<=mx;i++) for (int k=1;k<=mx;k++) for (int j=1;j<=mx;j++) (c.a[i][j]+=(LL)a.a[i][k]*b.a[k][j]%MOD), c.a[i][j]-=c.a[i][j]>=MOD?MOD:0;}Matrix ksm(Matrix x,int y){ Matrix ans;ans.unit(mx); while (y) { if (y&1) mul(ans,ans,x); mul(x,x,x);y>>=1; } return ans;}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&d[i]),mx=max(mx,d[i]); for (int i=1;i<=n;i++) a.a[mx-d[i]+1][mx]++,a.a[mx-d[i]+1][mx+1]++; for (int i=2;i<=mx;i++) a.a[i][i-1]++; mx++;a.a[mx][mx]++; a=ksm(a,m); printf("%d",(a.a[mx][mx]+a.a[mx-1][mx])%MOD); return 0;}
阅读全文
0 0
- 51nod 1582 n叉树 dp+矩阵乘法
- 51nod 1583 犯罪计划 dp+矩阵乘法+hash
- 51nod 1197 字符串的数量 V2 dp+矩阵乘法
- 51nod 1137 矩阵乘法
- 51nod 1137 矩阵乘法
- 51Nod 1137 矩阵乘法
- 【51Nod】1137 矩阵乘法
- 51nod--1137 矩阵乘法
- 51nod 1137 矩阵乘法
- 51Nod-1137-矩阵乘法
- 51Nod 1137 矩阵乘法
- 51Nod-1137 矩阵乘法
- 51Nod-1137-矩阵乘法
- 51nod 1137 矩阵乘法
- 51nod 1137矩阵乘法【矩阵】
- 51nod 1137 矩阵乘法(矩阵快速乘法)
- 51nod 1137 矩阵乘法(矩阵乘法)
- 51nod--1242 斐波那契数列第N项 (矩阵乘法优化)
- Visual Studio 单元测试 C++ 版
- IDEA 快捷键
- Linux的阻塞與非阻塞
- 如何编写bat文件来执行jar程序
- 底部导航:BottomTabBar的简单应用
- 51nod 1582 n叉树 dp+矩阵乘法
- c++类模板
- 公无渡河 公竟渡河
- 经典面试题:一栏定宽,另一栏自适应,且等高
- PLSQL Developer 不能连接 oracle 11g 64位 的解决办法
- Entity Framework 并发处理
- Linux下添加新硬盘,分区及挂载的详细步骤指导
- (一)谈论直男的问题
- Android.mk高级写法