zoukankan      html  css  js  c++  java
  • [BZOJ1009][HNOI2008]GT考试

    [BZOJ1009][HNOI2008]GT考试

    试题描述

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

    输入

    第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000

    输出

    阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

    输入示例

    4 3 100
    111

    输出示例

    81

    数据规模及约定

    见“输入

    题解

    设计 dp,f(i, j) 表示考号前 i 位匹配到不吉利串第 j 位的方案数,考虑在 f(i, j) 这个状态下,在后面添加一位,那么有可能转到 f(i+1, j+1) 或 f(i+1, k),那么我们可以暴力求出这个 k,构造一下转移矩阵,快速幂一下就好了。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 25
    int n, m, MOD;
    struct Matrix {
    	int n, m, A[maxn][maxn];
    	Matrix() { n = m = 0; memset(A, 0, sizeof(A)); }
    	Matrix operator * (const Matrix& t) const {
    		Matrix ans; ans.n = t.n; ans.m = m;
    		for(int i = 0; i <= ans.n; i++)
    			for(int j = 0; j <= ans.m; j++) {
    				ans.A[i][j] = 0;
    				for(int k = 0; k <= n; k++) {
    					ans.A[i][j] += (A[k][j] * t.A[i][k]) % MOD;
    					if(ans.A[i][j] >= MOD) ans.A[i][j] -= MOD;
    				}
    			}
    		return ans;
    	}
    	Matrix operator *= (const Matrix& t) {
    		*this = *this * t;
    		return *this;
    	}
    } b, t;
    char S[maxn], tmp[maxn];
    
    Matrix Pow(Matrix a, int b) {
    	Matrix ans = a, t = a; b--;
    	while(b) {
    		if(b & 1) ans *= t;
    		t *= t; b >>= 1;
    	}
    	return ans;
    }
    
    int main() {
    	n = read(); m = read(); MOD = read();
    	scanf("%s", S + 1);
    	
    	for(int i = 1; i <= m; i++) S[i] -= '0';
    	
    	for(int st = 0; st < m; st++) {
    		int cnt = 0;
    		for(int i = 1; i <= st; i++) tmp[++cnt] = S[i];
    		for(int x = 0; x <= 9; x++) {
    			tmp[++cnt] = x;
    			bool has = 0;
    			for(int j = 1; j <= cnt; j++) {
    				bool ok = 1;
    				int k, i;
    				for(k = j, i = 1; k <= cnt; k++, i++) if(tmp[k] != S[i]) {
    					ok = 0; break;
    				}
    				if(ok) {
    					has = 1;
    					t.A[i-1][st]++;
    					break;
    				}
    			}
    			if(!has) t.A[0][st]++;
    			cnt--;
    		}
    	}
    	b.A[0][0] = 1;
    	b.n = m; b.m = 0;
    	t.n = t.m = m;
    //	printf("\ "); for(int i = 0; i <= t.n; i++) printf("%d ", i); putchar('
    ');
    //	for(int i = 0; i <= t.n; i++) {
    //		printf("%d ", i);
    //		for(int j = 0; j <= t.m; j++) printf("%d ", t.A[i][j]);
    //		putchar('
    ');
    //	}
    	b *= Pow(t, n);
    	
    	int ans = 0;
    	for(int i = 0; i < m; i++) {
    		ans += b.A[i][0];
    		if(ans >= MOD) ans -= MOD;
    	}
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    v-model
    CSS background 属性
    渐变背景
    mint ui的field用法和修改样式的方法
    js 数组包含
    password 密码查询
    web 单一平台登录逻辑
    内存共享锁业务逻辑(原创)
    无限分类树操作
    根据日期获取,x岁x月x天
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5761881.html
Copyright © 2011-2022 走看看