zoukankan      html  css  js  c++  java
  • 【LOJ】#2128. 「HAOI2015」数字串拆分

    题解

    题中给的函数可以用矩阵快速幂递推

    我们记一个数组dp[i](这个数组每个元素是一个矩阵)表示从1到i所有的数字经过拆分矩阵递推的加和

    转移方法是
    (dp[i] = sum_{j = 0}^{i - 1} dp[j] * tr[j + 1][i])
    (tr[j][i])表示矩阵的([j,i])组成的数字次幂是什么样的矩阵

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define MAXN 100005
    #define mo 994711
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef long double db;
    typedef unsigned int u32;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {putchar('-');x = -x;}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    const int MOD = 998244353;
    int M,N;
    char s[505];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    struct Matrix {
        int f[6][6];
        Matrix() {memset(f,0,sizeof(f));}
        friend Matrix operator * (const Matrix &a,const Matrix &b) {
    	Matrix c;
    	for(int i = 0 ; i < M ; ++i) {
    	    for(int j = 0 ; j < M ; ++j) {
    		for(int k = 0 ; k < M ; ++k) {
    		    c.f[i][j] = inc(c.f[i][j],mul(a.f[i][k],b.f[k][j]));
    		}
    	    }
    	}
    	return c;
        }
        friend Matrix operator + (const Matrix &a,const Matrix &b) {
    	Matrix c;
    	for(int i = 0 ; i < M ; ++i) {
    	    for(int j = 0 ; j < M ; ++j) {
    		c.f[i][j] = inc(a.f[i][j],b.f[i][j]);
    	    }
    	}
    	return c;
        }
    }A[15],dp[505],tr[505][505];
    int g[15];
    Matrix fpow(Matrix x,int c) {
        Matrix res = A[0],t = x;
        while(c) {
    	if(c & 1) res = res * t;
    	t = t * t;
    	c >>= 1;
        }
        return res;
    }
    void Solve() {
        scanf("%s",s + 1);
        read(M);N = strlen(s + 1);
        for(int i = 0 ; i < M ; ++i) {
    	A[0].f[i][i] = 1;
        }
        dp[0] = A[0];
        g[0] = 1;
        for(int i = 1 ; i < M ; ++i) {
    	for(int j = 1 ; j <= i ; ++j) {
    	    g[i] = inc(g[i - j],g[i]);
    	}
        }
        for(int i = 0 ; i < M ; ++i) {
    	if(i != M - 1) A[1].f[i][i + 1] = 1;
    	A[1].f[M - 1][i] = 1;
        }
        for(int i = 2 ; i <= 9 ; ++i) {
    	A[i] = A[i - 1] * A[1];
        }
        for(int i = 1 ; i <= N ; ++i) {
    	Matrix r = A[0],t;
    	for(int j = i ; j <= N; ++j) {
    	    r = r * r;t = r;
    	    r = r * r;r = r * r;r = r * t;
    	    r = r * A[s[j] - '0'];
    	    tr[i][j] = r;
    	}
        }
        for(int i = 1 ; i <= N ; ++i) {
    	for(int j = 0 ; j < i ; ++j) {
    	    dp[i] = dp[i] + dp[j] * tr[j + 1][i];
    	}
        }
        int ans = 0;
        for(int i = 0 ; i < M ; ++i) ans = inc(ans,mul(g[i],dp[N].f[0][i]));
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    【Spring学习笔记-MVC-6】SpringMVC 之@RequestBody 接收Json数组对象
    【Spring学习笔记-MVC-1.1--】@PathVariable与@RequestParam、@CookieValue等比较
    【Oracle学习笔记-1】Win7下安装Oracle 10g
    【Oracle学习笔记-3】关于Oracle 10g中各种服务解析
    【前端编程-学习-5】系统加载提示
    【EasyUI学习-3】Easyui tabs入门实践
    【EasyUI学习-2】Easyui Tree的异步加载
    【Hibernate学习笔记-6.1】无连接表的N-1关联(单向)
    ArcGIS 要素合并
    Nginx 链接
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9674730.html
Copyright © 2011-2022 走看看