bnu 34895 Elegant String(矩阵快速幂)

题目链接:bnu 34895 Elegant String

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

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

#include <cstdio>
#include <cstring>

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;
}

bnu 34895 Elegant String(矩阵快速幂)

时间: 2024-10-28 21:51:54

bnu 34895 Elegant String(矩阵快速幂)的相关文章

bnu 34985 Elegant String(矩阵快速幂+dp推导公式)

Elegant String Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None Graph Theory      2-SAT     Articulation/Bridge/Biconnected Component      Cy

BNUOJ 34985 Elegant String 2014北京邀请赛E题 矩阵快速幂

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 题目大意:问n长度的串用0~k的数字去填,有多少个串保证任意子串中不包含0~k的某一个全排列 邀请赛上A的较多的一道题,比赛的时候死活想不出,回来之后突然就想通了,简直..... = =! 解题思路: 对于所有串我们都只考虑末尾最多有多少位能构成全排列的一部分(用l来表示),即最多有多少位不重复的数字出现,将问题转化为求末尾最多有k位能构成全排列的串的总数量 假设k为5,有一个

BNUOJ 34985 Elegant String 2014北京邀请赛E题 动态规划 矩阵快速幂

Elegant String Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k

2014 BNU 邀请赛E题(递推+矩阵快速幂)

Elegant String 题意:给定一个字符串,由0-k数字组成,要求该串中,子串不包含0-k全排列的方案数 思路:dp[i][j]表示放到i个数字,后面有j个不相同,然后想递推式,大概就是对应每种情况k分别能由那几种状态转移过来,在纸上画画就能构造出矩阵了,由于n很大,所以用快速幂解决 代码: #include <stdio.h> #include <string.h> const long long MOD = 20140518; int t; long long n; i

HDU5863 cjj&#39;s string game(DP + 矩阵快速幂)

题目 Source http://acm.split.hdu.edu.cn/showproblem.php?pid=5863 Description cjj has k kinds of characters the number of which are infinite. He wants to build two strings with the characters. The lengths of the strings are both equal to n. cjj also def

Acdreamoj1116(Gao the string!)字符串hash+二分+矩阵快速幂

Problem Description give you a string, please output the result of the following function mod 1000000007 n is the length of the string f() is the function of fibonacci, f(0) = 0, f(1) = 1... a[i] is the total number of times any prefix appear in the

HDU 5863 cjj&#39;s string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但是 m 很小的时候 发现此题DP并不合适.于是想可能是某种组合数学的问题可以直接公式算 看到题解的我.恍然大悟.对于这种数据.可以考虑一下矩阵快速幂优化的DP 首先要想到线性递推的 DP 式子 最直观的想法就是 dp[i][j] = 到第 i 个位置为止.前面最长匹配长度为 j 的方案数 但是如果仔

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

hdu 6198(矩阵快速幂)

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 119 暴力发现当4 12 33 88 232 和斐波那契数列对比  答案为 第2*k+3个数减1 直接用矩阵快速幂求的F[2*k+3]  然后减1 A=1,B=0; 然后矩阵快速幂2*k