Newcoder 84 D.k进制数(数论+map)

本文探讨了在特定进制下,如何计算满足特定条件的幸运数字子串的数量。通过定义d(x)为一个数的各位数之和,并在超过一位数时递归求和,直到结果为一位数。幸运数字定义为d(x)=b。文章提供了算法思路和代码实现,使用前缀和与哈希映射来高效解决该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

对于kkk进制数xxx,定义d(x)d(x)d(x)xxx的各数位的和的kkk进制表示,如果结果超过一位,则继续重复执行各数位求和操作,直至结果为111位。

比如说,在777进制下,d(35047)=d((3+5+0+4)7)=d(157)=d((1+5)7)=d(67)=6d(3504_7)=d((3+5+0+4)_7)=d(15_7)=d((1+5)_7)=d(6_7)=6d(35047)=d((3+5+0+4)7)=d(157)=d((1+5)7)=d(67)=6

定义xxx为幸运的,当且仅当d(x)=bd(x) = bd(x)=b

现在给定kkk进制下的nnn个数位a1a2...ana_1 a_2 ...a_na1a2...an,问其中有多少子串组成的数字是幸运的。

Input

第一行三个整数k,b,nk,b,nk,b,n

第二行nnn个整数aia_iai

(2≤k≤109,0≤b&lt;k,1≤n≤105,0≤ai&lt;k)(2\le k\le 10^9,0\le b&lt;k,1\le n\le 10^5,0\le a_i&lt;k)(2k109,0b<k,1n105,0ai<k)

Output

输出一个整数表示幸运的子串数。

Sample Input

10 5 6
3 2 0 5 6 1

Sample Output

5

Solution

显然d(x)=(x−1)%(k−1)+1d(x)=(x-1)\%(k-1)+1d(x)=(x1)%(k1)+1d(x)=0d(x)=0d(x)=0当且仅当xxx每位都为000,首先统计连续为000的段的个数resresres,如果b=0b=0b=0则答案即为resresres,如果b=k−1b=k-1b=k1,为方便统计,直接令d(x)=x%(k−1)d(x)=x\%(k-1)d(x)=x%(k1),如此求出的满足d(x)=0d(x)=0d(x)=0的子串本质上是d(x)=0,k−1d(x)=0,k-1d(x)=0,k1的子串数量和,该值减去resresres即为答案

现在考虑求满足d(x)=bd(x)=bd(x)=b的子串个数,令si=(a1+...+ai)%(k−1)s_i=(a_1+...+a_{i})\%(k-1)si=(a1+...+ai)%(k1),那么以iii为右端点的合法区间[j,i][j,i][j,i]需要满足si−sj−1≡b(mod k−1)s_i-s_{j-1}\equiv b(mod\ k-1)sisj1b(mod k1),用mapmapmap统计每种前缀和出现次数即可

Code

#include<cstdio>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=100005;
map<int,int>M;
int k,b,n,a[maxn];
int main()
{
	scanf("%d%d%d",&k,&b,&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	ll ans=0;
	for(int i=1,pre=1;i<=n;i++)
	{
		if(a[i])pre=i+1;
		else ans+=i-pre+1;
	}
	if(b==0)
	{
		printf("%lld\n",ans);
		return 0;
	}
	if(b==k-1)ans=-ans,b=0;
	else ans=0;
	M[0]=1;
	for(int i=1,res=0;i<=n;i++)
	{
		res=(res+a[i])%(k-1);
		ans+=M[(res-b+k-1)%(k-1)];
		M[res]++;
	}
	printf("%lld\n",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值