您的位置:首页 > 其它

HDU 5863 cjj's string game(矩阵快速幂)

2016-11-01 13:34 316 查看
对于给定的k个不同的字符,问对于用这k个字符构造出的长度为n的字符串,他们的对应位置子串长度最大值为m的数目是多少

对于dp[i][j]=dp[i-1][j-1]*k

dp[i][0]=(dp[i-1][0]+dp[i[1]+...+dp[i][m])*(k-1)*k

这几两个公司可以用矩阵来优化

#include<iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;
typedef long long ll;

const ll mod = 1e9 + 7;

struct mat
{
ll m[30][30];
int size;
mat()
{
memset(m, 0, sizeof m);
size = 0;
}
void clear()
{
memset(m, 0, sizeof m);
size = 0;
}
void E()
{
memset(m, 0, sizeof m);
for (int i = 0; i < size; i++)m[i][i] = 1;
}
friend mat operator*(const mat &a, const mat &b)
{
mat res;
if (a.size != b.size)return res;
res.size = a.size;
for (int i = 0; i < a.size; i++)for (int j = 0; j < b.size; j++)
{
res.m[i][j] = 0;
for (int k = 0; k < a.size; k++)
res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod;
}
return res;
}
friend mat operator^(const mat& a, ll q)
{
mat plus = a;
mat res;
res.size = a.size;
res.E();

while (q)
{
if (q & 1)res = res*plus;
plus = plus*plus;
q >>= 1;
}
return res;
}
};

int main()
{
int T;
cin >> T;
while (T--)
{
ll n, m, k;
scanf("%lld%lld%lld", &n, &m, &k);
mat start;
start.clear();
start.size = m + 1;
start.m[0][0] = 1;
mat trans;
trans.clear();
trans.size = m + 1;
for (int i = 0; i <= m; i++)
trans.m[i][0] = (k - 1)*(k);
for (int i = 1; i <= m; i++)
trans.m[i-1][i] = k;
mat t = trans;
t.size--;
trans = trans^n;
t = t ^ n;
mat a1 = start*trans;
start.size--;
mat a2 = start*t;
ll ans1 = 0, ans2 = 0;
for (int i = 0; i <= m; i++)ans1 = (ans1 + a1.m[0][i]) % mod;
for (int i = 0; i < m; i++)ans2 = (ans2 + a2.m[0][i]) % mod;
printf("%lld\n", (ans1 - ans2+mod)%mod);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  矩阵快速幂