AtCoder Beginner Contest 158 E - Divisible Substring

Divisible Substring

经过参考了各位大哥的代码和题解,我终于大概是了解了这题的思路
题意:
给定一个字符串,求字符串内任意连续子串组成的数字可以被 p p p整除的个数
思路:
首先我们从字符串的地位进行考虑
p = 2 o r p = 5 p = 2 or p=5 p=2orp=5时,此时我们考虑有最后一位数字可以被整除的必定对答案有贡献所以我们把这种情况单独提出来
其次我们考虑这样一个公式: 如果 s [ i − − j ] = ( s [ i ] − s [ j ] ) 1 0 j − i + 1 s[i--j]=\frac{(s[i]-s[j])}{10^{j-i+1}} s[ij]=10ji+1(s[i]s[j])
所以这个时候只要 s [ i ] % p s[i]\%p s[i]%p s [ j ] % p s[j]\%p s[j]%p模数相同则对答案有贡献
这个时候我们还需要对 q [ r e s ] q[res] q[res]++

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 2e5 + 10,M = 1e4 + 10;
char s[N];
int q[M];
ll ans;
int main()
{
    int p,n;
    cin >> n >> p;
    cin >> s+1;

    if(p == 2 || p == 5)
    {
        for(int i = n;i >= 1;i--)
        {
            if((s[i] - '0') % p == 0)ans += i;
        }
    }
    else
    {
        q[0] = 1;int po = 1,res = 0;
        for(int i = n;i >= 1;i--)
        {
            res = (res + (s[i] - '0') * po) % p;
            po = po * 10 % p;
            ans += q[res];//处理到i位时,连续余数和为now的个数是cnt[now],当前余数和now与之前余数和now,作差为0,那么之间的余数和为0的数能找到cnt[now]个,这就是能被p整除的数量。
            q[res]++;
        }
    }    
    cout << ans;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值