codeforces 514E-Darth Vader and Tree
作者:互联网
题意:有个无限大的有根树,每个节点都有N个孩子,每个孩子距离父亲节点的距离为di.求距离根节点距离<=x的节点个数.
思路:注意观察数据范围,每一个d[i]均小于等于100所以我们可以设dp[i]表示距离原点i的点的个数,sum[i]表示总和,最后求sum[x]即可。
状态转移方程
1 for(int i=1;i<=100;i++) 2 { 3 for(int j=1;j<=i;j++) 4 { 5 dp[i]=(dp[i]+dp[i-j]*cnt[j])%MOD; 6 } 7 sum[i]=(sum[i-1]+dp[i])%MOD; 8 }
但是因为x太大,而且dp[n+1]是每个dp[i]*cnt[n+1-i],令N=100,保存n+1前100个数,并用第101列更新sum,用矩阵快速幂求解即可。(C是单位矩阵!!!)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll MOD=(ll)1e9+7; 5 6 struct matrix 7 { 8 ll x,y; 9 ll a[112][112]; 10 matrix(){ 11 }; 12 matrix(ll xx,ll yy):x(xx),y(yy) 13 { 14 memset(a,0,sizeof(a)); 15 } 16 }Base; 17 18 matrix mul (matrix A,matrix B) 19 { 20 matrix C(A.x,B.y); 21 for(int i=1;i<=A.x;i++) 22 { 23 for(int j=1;j<=B.y;j++) 24 { 25 for(int k=1;k<=B.x;k++) 26 { 27 C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%MOD; 28 } 29 } 30 } 31 return C; 32 } 33 34 ll n,x,cnt[120],sum[120],dp[120]; 35 void init() 36 { 37 memset(cnt,0,sizeof(cnt)); 38 scanf("%lld%lld",&n,&x); 39 for(int i=1;i<=n;i++) 40 { 41 int p; 42 scanf("%d",&p); 43 cnt[p]++; 44 } 45 memset(sum,0,sizeof(sum)); 46 dp[0]=1; sum[0]=1; 47 for(int i=1;i<=100;i++) 48 { 49 for(int j=1;j<=i;j++) 50 { 51 dp[i]=(dp[i]+dp[i-j]*cnt[j])%MOD; 52 } 53 sum[i]=(sum[i-1]+dp[i])%MOD; 54 } 55 56 Base.x=101; Base.y=101; 57 //123...97 98 99 100 101(ans) 58 59 //000...000 len[100] len[100] 60 //100...000 len[99] len[99] 61 //010...000 len[98] len[98] 62 //......................... 63 //000...001 len[1] len[1] 64 //000...000 0 1 65 for(int i=1;i<=99;i++) 66 { 67 Base.a[i+1][i]=1; 68 Base.a[i][100]=cnt[101-i]; 69 Base.a[i][101]=cnt[101-i]; 70 } 71 Base.a[100][100]=Base.a[100][101]=cnt[1]; 72 Base.a[101][101]=1; 73 } 74 75 matrix qpow (matrix Base,ll b) 76 { 77 matrix C(Base.x,Base.y); 78 for(int i=1;i<=101;i++) C.a[i][i]=1;//danweijuzhen 79 while(b) 80 { 81 if(b%2==1) C=mul(C,Base); 82 b/=2; 83 Base=mul(Base,Base); 84 } 85 return C; 86 } 87 88 int main() 89 { 90 init(); 91 matrix A(1,101); 92 for(int i=1;i<=100;i++) A.a[1][i]=dp[i]; 93 A.a[1][101]=sum[100]; 94 if(x<=100) 95 { 96 printf("%lld\n",sum[x]); 97 return 0; 98 } 99 A=mul(A,qpow(Base,x-100)); 100 printf("%lld\n",A.a[1][101]%MOD); 101 return 0; 102 }View Code
标签:matrix,ll,Darth,距离,Vader,100,514E,sum,dp 来源: https://www.cnblogs.com/Forever-666/p/10925800.html