设为首页 加入收藏

TOP

bnu 34895 Elegant String(矩阵快速幂)
2015-07-24 05:53:58 来源: 作者: 【 】 浏览:6
Tags:bnu 34895 Elegant String 矩阵 快速

题目链接:bnu 34895 Elegant String

题目大意:给定n和k,表示有一个长度为n的序列,序列中的元素由0~k组成,问说有多少个串满足不包含0~k的全排列。

解题思路:矩阵快速幂,根据dp[i][j]表示说第i为有j个相同,写出递推式,根据递推式求出矩阵。

#include 
   
     #include 
    
      typedef long long ll; const ll MOD = 20140518; const int N = 20; struct mat { int r, c; ll s[N][N]; void init (int k, int sign) { memset(s, 0, sizeof(s)); if (sign) { r = c = k; for (int i = 1; i <= r; i++) { for (int j = i; j <= r; j++) s[i][j] = 1; if (i == r) continue; s[i+1][i] = k+1-i; } } else { r = k; c = 1; s[1][1] = k+1; } } void put() { for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) printf("%lld ", s[i][j]); printf("\n"); } } }; mat mul(mat a, mat b) { mat ans; memset(ans.s, 0, sizeof(ans.s)); for (int i = 1; i <= a.r; i++) { for (int j = 1; j <= b.c; j++) { for (int x = 1; x <= a.c; x++) ans.s[i][j] = (ans.s[i][j] + a.s[i][x] * b.s[x][j])%MOD; } } ans.r = a.r; ans.c = b.c; return ans; } ll n; int k; ll solve (ll x) { if (x == 1) return k+1; x--; mat ans, cur; ans.init(k, 0); cur.init(k, 1); while (x) { if (x&1) ans = mul(cur, ans); cur = mul(cur, cur); x /= 2; } int sum = 0; for (int i = 1; i <= k; i++) sum = (sum + ans.s[i][1]) % MOD; return sum; } int main () { int cas; scanf("%d", &cas); for (int i = 1; i <= cas; i++) { scanf("%lld%d", &n, &k); printf("Case #%d: %lld\n", i, solve(n)); } return 0; }
    
   
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇十进制转二进制-快速算法 下一篇hdu 4828 Grids(拓展欧几里得+卡..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: