Codeforces 327C 快速幂+等比数列求和+乘法逆元

2024-03-30 02:58

本文主要是介绍Codeforces 327C 快速幂+等比数列求和+乘法逆元,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:http://codeforces.com/problemset/problem/327/C
There is a long plate s containing n digits. Iahub wants to delete some digits (possibly none, but he is not allowed to delete all the digits) to form his “magic number” on the plate, a number that is divisible by 5. Note that, the resulting number may contain leading zeros.

Now Iahub wants to count the number of ways he can obtain magic number, modulo 1000000007 (109 + 7). Two ways are different, if the set of deleted positions in s differs.

Look at the input part of the statement, s is given in a special form.

Input
In the first line you’re given a string a (1 ≤ |a| ≤ 105), containing digits only. In the second line you’re given an integer k (1 ≤ k ≤ 109). The plate s is formed by concatenating k copies of a together. That is n = |a|·k.

Output
Print a single integer — the required number of ways modulo 1000000007 (109 + 7).

题意

有一个循环了n次字符串a,a中的字符均为数字。
现在要删去其中的若干字符(不能全删),使得最后剩下的数字是5的倍数。

思路

先说一个基本但必须用到的结论:若一个数是5的倍数,则它末位是5的倍数(即为5或0)。
设这个字符串为a[1]a[2]a[3]...a[p]...a[n]。
首先需要思考一个问题:以a[p]结尾的数有多少个。
答案是:2^(p-1)。
这个的推导过程很简单,这里就不赘述了。
并注意:数据过大,需要快速幂。然后要想一个问题:由于循环次数n过大,从前到后枚举一次不现实,需要用数学方法简化。
由于它循环n次每次都是相同的字符串,所以易得
以a[p]结尾的数个数+以a[p+len]结尾的数个数+...+a[p+len*(n-1)]
=2^(p-1)+2^(p+len-1)+...+2^(p+len*(n-1)-1)
=2^(p-1)*[2^0+2^len+...+2^(len*(n-1))]
然后用等比数列求和公式化简,得
原式=2^(p-1)*(2^(len*n)-1/2^len-1)。现在又面临一个更大的问题:
结果需要对10^9+7取模,但是在上式分母上下都是快速幂,取模后会有精度丢失的问题。
所以需要引进乘法逆元来完成。乘法逆元的定义是:如果ab≡1 (modp),则说b是mod p意义下的乘法逆元。
在此题中,需要求(a/b)%p的值,则设k是b的乘法逆元,则(a/b)%p=(a*k)%p。
这个等式的证明可以看这篇题解:
http://www.cnblogs.com/tiankonguse/archive/2012/08/14/2638949.html
而求b的乘法逆元可以运用费马小定理:
由b^(p-1)≡1 (modp),得b的乘法逆元是b^(p-2)。
所以问题就解决了。PS.变量最好用long long,如果一个int和一个long long相乘可能会出错。

代码

#include<stdio.h>
#include<cstring>
using namespace std;
const long long mod=1000000007;
long long fastpow(long long b,long long p,long long k) {b%=k;long long ret=1;while(p) {if(p&1) ret=(ret%k)*(b%k)%k;p>>=1;b=(b%k)*(b%k)%k;}return ret%mod;
}
char a[1000001];
int main() {
//  freopen("data.txt","r",stdin);long long k,len;gets(a);scanf("%I64d",&k);len=strlen(a);long long ans=0;for(int i=0; i<len; i++) {if(a[i]=='5' || a[i]=='0') {ans=(ans+fastpow(2,i,mod))%mod;}}long long tmp=fastpow(2,len,mod)%mod;long long p=fastpow(2,len*k,mod)%mod;tmp=((1-tmp)%mod+mod)%mod;tmp=fastpow(tmp,mod-2,mod);p=((1-p)%mod+mod)%mod;ans=(ans*p)%mod*tmp%mod;
//  if(a[0]=='8' && a[1]=='4')  printf("%I64d %I64d ",tmp,p);printf("%I64d",ans);return 0;
}
/*
27755776656210607832788619414635535178188775623838313967013958143619017005079991285469853503718562504927535176713879737569375166451462839457844835806559098448980069427607
151
*/

这篇关于Codeforces 327C 快速幂+等比数列求和+乘法逆元的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/860316

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

Python如何快速下载依赖

《Python如何快速下载依赖》本文介绍了四种在Python中快速下载依赖的方法,包括使用国内镜像源、开启pip并发下载功能、使用pipreqs批量下载项目依赖以及使用conda管理依赖,通过这些方法... 目录python快速下载依赖1. 使用国内镜像源临时使用镜像源永久配置镜像源2. 使用 pip 的并