题解:P10262 [GESP样题 六级] 亲朋数

看到算法标签想出来的。

Idea

dpi,jdp_{i,j} 表示当前枚举到了第 ii 位,子串化为十进制 对 pp 取模的余数为 jj 的子串数量。

sis_ipp 取余的余数为 qq

j1j_1 为上一个枚举到的 jjj2j_2 为我们需要转移的 jj,由余数的性质我们可得:j2=(10×j1+q) modpj_2=(10\times j_1+q)\bmod p。其实就是将前一个数乘 1010 然后加上 sis_i 代表的十进制数对 pp 取余的结果。

最后答案是什么?亲朋数是 pp 的倍数,换而言之,亲朋数对 pp 取模余数为 00。所以答案就是 dpi,0dp_{i,0} 的和。

这题略卡空间,所以需要滚动数组优化。

Code

#include<bits/stdc++.h>
using namespace std;
long long dp[129],f[129];
int p;
string s;
long long ans=0;
int main(){
	cin>>p;
	cin>>s;
	s=' '+s;
	int n=s.length()-1;
	for(int i=1;i<=n;i++){
		int q=s[i]-'0';
		q=q%p;
		for(int j=0;j<p;j++){
			f[j]=dp[j]; 
			dp[j]=0;
		}
		for(int j=0;j<p;j++){
			dp[(j*10+q)%p]+=f[j];
		}
		dp[q]++;//可能自己独自成为一个亲朋数,需要把这个数自己算上
		ans+=dp[0];
	}
	cout<<ans;
	return 0;
}

Tip

本题答案最多时可以达到 5×10115\times 10^{11},所以需要开 long long。例如当 p=2p=2ss10610^622 构成时,所有情况都满足。

但是本题数据略水,所以不用开 long long 也能过。

posted @   Weslie_qwq  阅读(35)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示