zoukankan      html  css  js  c++  java
  • 競プロ典型 90 問泛做

    被叉姐推荐了競プロ典型 90 問

    ★7

    005 - Restricted Digits(★7)

    可以容易思考出矩阵乘法的做法\(O(B^3logn)\)
    但其实我们发现其实质为多项式乘法,考虑进位后我们仍旧可以用\(B^2\)处理两个答案合并。
    那么可以直接分治即可。

    005 - Restricted Digits(★7)
    #include<iostream>
    #include<cstdio>
    #define ll long long 
    #define N 200005
    #define P ((ll)1e9 + 7)
    
    ll n,B,K,pw[64],pre[64][1005],f[64][1005];
    int a[N];
    
    int main(){
    	scanf("%lld%lld%lld",&n,&B,&K);
    	for(int i = 1;i <= K;++i)
    	scanf("%d",&a[i]),a[i] %= B;
    	pw[0] = 10;
    	for(int i = 1;i <= 61;++i)
    	pw[i] = pw[i - 1] * pw[i - 1] % B;
    	for(int i = 1;i <= K;++i)
    	pre[0][a[i]] ++ ;
    	for(int i = 0;i <= 61;++i)
    	for(int j = 0;j < B;++j)
    	for(int k = 0;k < B;++k){
    		int to = (j * pw[i] + k) % B;
    		pre[i + 1][to] = pre[i + 1][to] + pre[i][j] * pre[i][k];
    		pre[i + 1][to] %= P;
    	}
    	f[0][0] = 1;
    	for(int i = 0;i <= 61;++i){
    		if(n & (1ll << i))
    		for(int j = 0;j < B;++j)
    		for(int k = 0;k < B;++k){
    		int to = (j * pw[i] + k) % B;
    		f[i + 1][to] = f[i + 1][to] + pre[i][j] * f[i][k];
    		f[i + 1][to] %= P;
    		}
    		else 
    		for(int j = 0;j < B;++j)
    		f[i + 1][j] = f[i][j];
    	}
    	std::cout<<f[62][0]<<std::endl;
    }	
    
  • 相关阅读:
    递归与分治4
    递归与分治3
    递归与分治2
    递归与分治1
    枚举与递推3
    枚举与递推2
    求编译器中数的最值(c++)
    移动小球链表实现
    阶乘的精确值
    while((c = getchar()) != EOF)(键盘输入问题)
  • 原文地址:https://www.cnblogs.com/dixiao/p/15661004.html
Copyright © 2011-2022 走看看