您的位置:首页 > 其它

矩阵快速幂

2016-02-23 23:24 344 查看
Darth Vader and Tree
http://codeforces.com/contest/514/problem/E
dp[i],表示距离为i的点有多少个

前dp[100]可以表示出来

然后构造矩阵

A.B



可以发现每次矩阵乘以矩阵B,A中的就会变成(dp[k+1],dp[k+2],,,,,,dp[k+100],1到dp[k+100]之和)

所以再乘上X-100个B矩阵就能得到最终值

代码如下
/*
ID: meixiny1
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define PI 3.1415926535898
//#define LOCAL
int a[100002],cnt[1002];
ll dp[205];
struct Matrix
{
ll a[102][102];
Matrix() {memset(a,0,sizeof a);}
};
Matrix mul(Matrix A, Matrix B){
Matrix C;
for(int i=1;i<=101;i++){
for(int j=1;j<=101;j++){
for(int k=1;k<=101;k++)
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]%MOD)%MOD;
}
}
return C;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
int n,x;scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;
MEM(dp,0);
dp[0]=1;
for(int i=1;i<=100;i++){
for(int j=0;j<=i;j++){
dp[i]=(dp[i]+dp[i-j]*cnt[j]%MOD)%MOD;
}
}
if(x<=100){
ll tot = 0;
for(int i=0;i<=x;i++)tot = (tot + dp[i])%MOD;
cout <<tot << endl;
}
else{
//构造数组
Matrix A;
for(int i=2;i<=100;i++)A.a[i][i-1]=1;
for(int i=1;i<=100;i++){
A.a[i][100]=cnt[101-i];
A.a[i][101]=cnt[101-i];
}
A.a[101][101]=1;
Matrix T;
for(int i=1;i<=101;i++)T.a[i][i]=1;
x -= 100;
while(x){
if(x&1){
T = mul(T,A);
}
A = mul(A,A);
x >>=1;
}
Matrix B;
ll tot = 0;
for(int i=1;i<=101;i++){
tot += dp[i];
if(i<=100)B.a[1][i]=dp[i];
else B.a[1][101]= tot;
}
B = mul(B,T);
cout << (B.a[1][101]+1)%MOD << endl;
}
return 0;
}
矩阵快速幂也可以用来求斐波那契

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: