• BZOJ1009


    题目

    阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
    他的不吉利数字A1A2... Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am。(A1和X1可以为0)

    题解

    看到题目,很自然地就能想到可以用数位dp来解决。但是这题位数太大,不能直接计算(写题的时候被这个限制卡了qwq)。
    对于很大的位数,可以考虑用矩阵加速。只要dp转移式是个一次多项式,就可以矩阵加速。
    设dp[i][p]为当前在第i位时,匹配到的不吉利的数字长度为p+1。
    预处理一个f[p][d]代表不吉利数字位置p后添加数字d到达的位置,这个可以用kmp预处理。然后套矩阵快速幂即可。

    #include <bits/stdc++.h>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define FILE freopen(".//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
    #define FI freopen(".//data_generator//in.txt","r",stdin)
    #define FO freopen("res.txt","w",stdout)
    #define pb push_back
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
    
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    
    const int N = 50;
    const double eps = 1e-5;
    
    int nt[N];
    int f[N][N];
    char s[N];
    int k;
    
    struct Mat {
        int n;
        int arr[N][N];
        Mat(int n, int v) : n(n){
            if(v)
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < n; j++) {
                        arr[i][j] = (i == j);
                    }
                }
            else 
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < n; j++) {
                        arr[i][j] = 0;
                    }
                }
        }
        Mat operator*(Mat & rhs) {
            Mat tmp(n, 0);
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    for(int kk = 0; kk < n; kk++) {
                        tmp.arr[i][j] += (arr[i][kk] * rhs.arr[kk][j]) % k;
                        tmp.arr[i][j] %= k;
                    }
                }
            }
            return tmp;
        }
        Mat(const Mat & rhs) {
            n = rhs.n;
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    arr[i][j] = rhs.arr[i][j];
                }
            }
        }
        void print() {
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    cout << arr[i][j] << " ";
                }
                cout << endl;
            }
        }
    };
    
    Mat qpow(Mat a, int b) {
        Mat res(a.n, 1);
        while(b) {
            if(b & 1) res = res * a;
            a = a * a;
            b = b >> 1;
        }
        return res;
    }
    
    
    void getnext() {
        int i = 0, j = -1;
        int n = strlen(s);
        nt[i] = j;
        while(s[i]) {
            if(j == -1 || s[i] == s[j]) {
                i++, j++;
                nt[i] = j;
            } else {
                j = nt[j];
            }
        }
        for(int p = 0; p <= n; p++) {
            for(int i = 0; i <= 9; i++) {
                int tar = p;
                if(s[tar] - '0' == i) {
                    f[p][i] = tar + 1;
                } else {
                    f[p][i] = nt[p] < 0 ? 0 : f[nt[p]][i];
                }
            }
        }
    }
    
    
    int main() {
        IOS;
        int n, m;
        cin >> n >> m >> k;
        cin >> s;
        getnext();
        Mat ans(m, 0);
        for(int p = 0; p < m; p++) {
            for(int d = 0; d <= 9; d++) {
                ans.arr[f[p][d]][p]++;
            }
        }
        ans = qpow(ans, n);
        int res = 0;
        for(int i = 0; i < m; i++) {
            res += ans.arr[i][0];
            res %= k;
        }
        cout << res << endl;
    }
    
  • 相关阅读:
    Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
    JavaScript 多级联动浮动(下拉)菜单 (第二版)
    JavaScript在IE浏览器和Firefox浏览器中的差异总结
    IE和FF对CSS兼容问题
    XHTML的特征(规范)
    总结引入CSS样式方式中的link和import的区别
    CSS知识精化集全,每天更新一点点,自己总结。
    今天遇见了setTimeout()函数
    jquery的发展由来和深入理解(一)
    左边导航条动态增加或缩短高度以及放大缩小问题的解决方法
  • 原文地址:https://www.cnblogs.com/limil/p/13502283.html
Copyright © 2020-2023  润新知