zoukankan      html  css  js  c++  java
  • [CodeForces][数学][组合][快速幂] CF327C Magic Five

    题面

    首先可以想到 (5) 的倍数一定以 (5)(0) 结尾,也就是我们选择的一段数字,只要保证结尾为 (0)(5),前面数字是什么是无关答案,可以任选的。、
    那么我们就先考虑在 a 这个串中如何统计答案,最后将 (k) 个串平起来的答案直接乘上去就好了。

    对于字符串 a,记最高位为第 (0) 位,最低位为第 (n-1) 位,根据乘法及加法原理,有:

    [ans_a = 2^0 imes (a_0 == 5 || a_0 == 0) + 2^1 imes (a_1 == 5 || a_1 == 0) + cdots + 2^{n-1} imes (a_{n-1} == 5 || a_{n-1} == 0) ]

    那么我们对于 (k)a,有这样的方案:

    [ans_1 = ans_a imes (2^n)^0 \ ans_2 = ans_a imes (2^n)^1 \ ans_3 = ans_a imes (2^n)^2 \ cdots \ ans_k = ans_a imes (2^n)^{k-1} ]

    对答案求一下和,发现其实就是等比数列求和,得到以下结果:

    [ANS = ans_1 imes frac{2^{nk}-1}{2^n-1} ]

    其中 (n) 为字符串长度。
    于是这道题只剩下轻松愉快的快速幂和费马小定理求逆元了。

    代码:

    // 只要保证最后一位是 0 或 1,就能被 5 整除
    // 所以答案是每一个 5 或非前导 0 之前的部分求方案
    // s 不需要显式的建出来,每一个串对应多更新答案
    // 前导 0 计算在结果中
    
    # include <iostream>
    # include <cstdio>
    # include <string>
    
    const long long MOD = 1e9+7;
    
    long long QPow(long long x, long long y){
    	long long ans = 1, base = x%MOD;
    	while(y){
    		if(y & 1){
    			ans = (ans * base) % MOD;
    		}
    		base = (base * base) % MOD;
    		y >>= 1;
    	}
    	return ans;
    }
    
    long long Inv(long long x){
    	return QPow(x, MOD-2);
    }
    
    int main(){
    	std::string a; int k;
    
    	std::cin>>a>>k;
    
    	long long ans = 0;
    	for(int i = 0; i <= a.length()-1; i++){
    		if(a[i] == '0' || a[i] == '5'){
    			ans = (ans + QPow(2, i)) % MOD;
    		}
    	}
    
    	printf("%lld", (((ans * (QPow(2, 1ll*a.length()*k) - 1)) % MOD) * Inv(QPow(2, a.length())-1)) % MOD);
    
    	return 0;
    }
    
  • 相关阅读:
    BouncyCastle 密钥转换
    java中公钥,私钥,pkcs1格式,pkcs8格式互转
    与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence
    RSA加解密时报algid parse error, not a sequence错误
    RSA算法原理(二)
    RSA算法原理(一)
    RSA加密的java实现---亲测
    Linux SSH和SFTP服务分离
    文件夹的rwx权限
    AMD 和 CMD 的区别有哪些?
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13726429.html
Copyright © 2011-2022 走看看