【codeforces 514E】Darth Vader and Tree
2017-10-04 18:44
411 查看
【题目链接】:http://codeforces.com/problemset/problem/514/E
【题意】
无限节点的树;
每个节点都有n个儿子节点;
且每个节点与其第i个节点的距离都是ai;
问你与根节点的距离不超过x的节点个数;
【题解】
考虑一个非常不靠谱的DP方程
f[i]=∑(f[i-j]*cnt[j]);
这里f[i]表示与根节点的距离为i的节点个数;
cnt[j]表示ai的值中为j的ai的个数;(即与儿子节点距离为j的边的个数);
因为ai最大值为100,所以j∈[1..100]
i∈[0..x]
求和就是答案了;
但x有1e9的规模;
需要优化;
矩阵!
这里先把f[1..100]的值算出来,同时把f[1..100]累加起来->sum;
得到矩阵A
然后再构造一个系数矩阵B
cnt的意义如上;
这里之所以把sum加进去,是为了便于最后直接输出结果;
不然我们这样递推如果只得出f[x]的话,你没办法加起来;
前100列用于递推出f[i+1];
第100列用于求和∑f[1..i];
求
A×Bx−100
最后答案直接输出右下角那个值a[101][101]就好;
sum一开始加上一个1;
因为本身也算.
【Number Of WA】
0
【完整代码】
#include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define mp make_pair #define ps push_back #define fi first #define se second #define rei(x) cin >> x #define ms(x,y) memset(x,y,sizeof x) typedef pair<int,int> pii; typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1}; const int dy[9] = {0,0,0,-1,1,-1,1,-1,1}; const double pi = acos(-1.0); const int N = 110; const LL MOD = 1e9+7; int n,x; LL dp ,cnt ,sum; const int G = 101; //矩阵大小 struct MX { int v[G+5][G+5]; void O() { ms(v, 0); } void E() { ms(v, 0); for (int i = 1; i <= G; ++i)v[i][i] = 1; } void P() { for (int i = 1; i <= G; ++i) { for (int j = 1; j <= G; ++j)printf("%d ", v[i][j]); puts(""); } } MX operator * (const MX &b) const { MX c; c.O(); for (int k = 1; k <= G; ++k) { for (int i = 1; i <= G; ++i) if (v[i][k]) { for (int j = 1; j <= G; ++j) { c.v[i][j] = (c.v[i][j] + (LL)v[i][k] * b.v[k][j]) % MOD; } } } return c; } MX operator + (const MX &b) const { MX c; c.O(); for (int i = 1; i <= G; ++i) { for (int j = 1; j <= G; ++j) { c.v[i][j] = (v[i][j] + b.v[i][j]) % MOD; } } return c; } MX operator ^ (LL p) const { MX y; y.E(); MX x; memcpy(x.v, v, sizeof(v)); int num[64+2],cnt = 0; while (p) { num[++cnt] = p&1; p>>=1; } for (int i =cnt;i>=1;i--) { y = y*y; if (num[i]) y = y*x; } return y; } }a,xishu; int main() { //freopen("F:\\rush.txt","r",stdin); ios::sync_with_stdio(false); rei(n),rei(x); rep1(i,1,n) { int d; rei(d); cnt[d]++; } dp[0] = 1; rep1(i,1,min(x,100)) rep1(j,1,i) dp[i] = (dp[i]+(dp[i-j]*cnt[j])%MOD)%MOD; sum=1; rep1(i,1,min(x,100)) sum=(dp[i]+sum)%MOD; if (x<=100) return cout << sum << endl,0; a.O(); rep1(i,1,100) a.v[1][i] = dp[i]; a.v[1][101]= sum; xishu.O(); rep1(i,2,100) xishu.v[i][i-1] = 1; rep1(i,1,100) xishu.v[i][100]=xishu.v[i][101] = cnt[101-i]; xishu.v[101][101] = 1; a = a*(xishu^(x-100)); cout << a.v[1][101]<<endl; //printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC); return 0; }
相关文章推荐
- Codeforces 514E Darth Vader and Tree【Dp+矩阵快速幂优化】
- Codeforces 514E. Darth Vader and Tree DP+矩阵快速幂
- Codeforces 514E Darth Vader and Tree【Dp+矩阵快速幂优化】
- 【 Codeforces 514E 】Darth Vader and Tree - DP 矩乘转移
- Codeforces 514E Darth Vader and Tree DP + 矩阵快速幂
- 矩阵快速幂DP Darth Vader and Tree : CodeForces - 514E
- codeforces 514E E. Darth Vader and Tree(矩阵应用)
- codeforces 514E E. Darth Vader and Tree(矩阵快速幂 )
- Codeforces 682C Alyona and the Tree DP
- codeforces-342E-Xenia and Tree
- Appleman and Tree - CodeForces 461 B 树形dp
- Codeforces 842 C. Ilya And The Tree 树上dp
- Codeforces 764C Timofey and a tree(思路)
- 【Codeforces Round #395 (Div. 2)】Codeforces 764C Timofey and a tree
- codeforces 463E Caisa and Tree 栈+dfs
- Codeforces 763A-Timofey and a tree
- 【CodeForces438E】The Child and Binary Tree
- codeforces 711C. Bear and Tree Jumps(树上距离)
- 【Codeforces 736C】 Ostap and Tree【树形DP】
- Codeforces 711C. Bear and Tree Jumps【树形dp好题】