Codeforces 514E 矩阵快速幂
来源:互联网 发布:linux 局域网传文件 编辑:程序博客网 时间:2024/05/19 02:01
/*有这样一棵树,每个节点都有n(1~100000)个儿子,伸向n个儿子的边从左到右分别为di(1~100)这棵树是无穷延伸的,求距离根节点距离小于等于x(1e9)的节点数目解法:好题,算是寒假第一题,手生,没做出来都解法是矩阵快速幂设dp[i]为距离根节点距离恰好为i的数目,首先很好想到dp[i+j] += dp[i]*cnt[j]那么这样就是一个很明显的矩阵构造矩阵的构造比较有技巧矩阵A(1x101)[dp[1] , dp[2] , ... , dp[100] , sigma(dp[i],i=0~100) ]矩阵B(101x101)[0 0 0 ... 0 0 cnt[100] cnt[100]][1 0 0 ... 0 0 cnt[99] cnt[99] ][0 1 0 ... 0 0 cnt[98] cnt[98] ][0 0 1 ... 0 0 cnt[97] cnt[97] ]...[0 0 0 ... 0 1 cnt[1] cnt[1] ][0 0 0 ... 0 0 0 0 ]*/#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <iostream>#include <set>using namespace std;#define ll long long#define pb push_back#define PII pair<ll,ll>#define ALL(x) (x).begin(),(x).end()const int N=111;//matrix size#define TYPE intint A[111][111];int B[111][111];int C[111][111];int tmp[111][111];const int MAXN = 101111;int d[MAXN];const int MOD = 1e9+7.5;void printfm(TYPE A[N][N],int n,int m){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ printf("%d%c",A[i][j],(j==m-1)?'\n':' '); } } printf("\n");}void mul(TYPE A[N][N],TYPE B[N][N],TYPE t[N][N],int n,int m,int l)//A 为n*m的矩阵,B为m*l的矩阵,t为结果矩阵{ TYPE tmp[N][N];//为了防止冲突 for(int i=0;i<n;i++){ for(int j=0;j<l;j++){ tmp[i][j]=0; for(int k=0;k<m;k++) tmp[i][j]=(tmp[i][j]+1LL*A[i][k]*B[k][j]%MOD)%MOD; } } for(int i=0;i<n;i++) for(int j=0;j<l;j++) t[i][j]=tmp[i][j];}void expo(TYPE p[N][N],TYPE e[N][N],int k,int n)//P为n*n的矩阵,k为计算k次幂,e为结果矩阵{ if(k!=1){ for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) e[i][j] = (i == j); while(k){ if(k&1) mul(e,p,e,n,n,n); mul(p,p,p,n,n,n); k>>=1; } }else{ for(int i=0;i<n;i++) for(int j=0;j<n;j++) e[i][j]=p[i][j]; }}int dp[111];int cnt[111];int main(){ //freopen("in.txt","r",stdin); int n,x; scanf("%d%d",&n,&x); for(int i=1;i<=n;i++){ scanf("%d",&d[i]); cnt[d[i]]++; } dp[0]=1; for(int i=0;i<=100;i++){ for(int j=0;j<=100;j++){ dp[i+j] += 1LL*dp[i]*cnt[j]%MOD; dp[i+j]%=MOD; } } int sum=1; for(int i=0;i<100;i++) A[0][i]=dp[i+1],sum=(sum+dp[i+1])%MOD; A[0][100] = sum; for(int i=0;i<100;i++) B[i][99] = B[i][100] = cnt[100-i]; B[100][100] = 1; for(int i=1;i<=99;i++) B[i][i-1] = 1; if(x<=100){ int ans=0; for(int i=0;i<=x;i++) ans=(ans+dp[i])%MOD; printf("%d\n",ans); }else{ //printfm(B,10,10); expo(B,tmp,x-100,101); mul(A,tmp,C,1,101,101); printf("%d\n",C[0][100]); } return 0;}
0 0
- Codeforces 514E 矩阵快速幂
- codeforces 514E E. Darth Vader and Tree(矩阵快速幂 )
- Codeforces 691E Xor-sequences【矩阵快速幂,好题】
- Codeforces 691E Xor-sequences(矩阵快速幂)
- Codeforces 691 E Xor-sequences 矩阵快速幂
- CodeForces-691E Xor-sequences(矩阵快速幂)
- codeforces 691E Xor-sequences(矩阵快速幂)
- codeforces #373(div 2) E (线段树+矩阵快速幂)
- Codeforces 691E Xor-sequences【矩阵快速幂,好题】
- Codeforces Round #226 (Div. 2) E(矩阵快速幂)
- CodeForces 60 E.Mushroom Gnomes(矩阵快速幂)
- 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+矩阵快速幂优化】
- 514E (矩阵快速幂+DP)
- Codeforces 385E Bear in the Field(矩阵快速幂)
- Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)
- 理解javascript中所有的函数参数是按值传递
- LeetCode322. Coin Change
- 深度实践嵌入式linux系统移植 光盘下载地址
- junit4X系列--Rule
- 网络爬虫基本原理
- Codeforces 514E 矩阵快速幂
- junit4X系列--Builder、Request与JUnitCore
- java提高篇(四)-----抽象类与接口
- 【LeetCode】9. Palindrome Number
- iOS-对话框的应用
- java中基本类型的参数传递和引用类型的参数传递
- 数据集参数取值构件
- html5实现滚动文字
- junit4X系列--Exception