Atcoder ABC E - Divisible Substring mathematical thinking + + substring

Atcoder ABC E - Divisible Substring

The meaning of problems

Is a long string of digits n (2e5) of a given prime number p (1E4), p substring be divisible (continuous) Number

Thinking

Since p is a prime number, so think of a Condition of Prime. The most simple is dp [i] [j] bit i is the lowest bit modp remainder j is the number of sub-strings, but the transfer is np, we can think about it, what is the state of excess, per transfer times should take the J 10 + S [i] - '0' this operation has no significance does it have? We assume that p and 10 are relatively prime, in fact, does not make sense, because if p prime to 10 and then added to the back of each number no matter how many zeros will not change the situation it is divisible and p. Small prove: Add 0 is equivalent to a multiplication (2 * 5) prime factors, but no prime factor p 2 and 5, it will not be affected. The question then is converted into, for example, s [1] s [2] s [3] s [4] s [5] s [6] if s [4] s [5] can be divisible by p, then the s [4] s [5] can also be divisible by p 0, which means that we just record the remainder of the film p for each suffix, the same can be combined two by two. For modp suffix is equal to 0, but also to add additional of a single take.
Remember, above the foundation 10 and the prime p, the prime number greater than 10 is in fact certainly not prime and 10, it can be appreciated from the unique decomposition theorem. And less than 10 5 and 2 are relatively prime and 10, as far as the sub-strings to 2 or 5 at the end there are several, the present problem is solved

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define F first
#define S second
#define mkp make_pair
#define pii pair<int,int>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=2e5+5;
char s[maxn];
ll dp[10000+5];

int main(){
    ll n,p;
    cin>>n>>p;
    cin>>(s+1);
    ll ans=0;
    if(p==2||p==5){
        for(int i=1;i<=n;i++){
            if((s[i]-'0')%p==0){
                ans+=i;
            }
        }
    }
    else {
        ll tmp=0;
        ll base=1;
        for(int i=n;i>=1;i--){
            tmp=(tmp+(s[i]-'0')*base)%p;
            base=(base*10)%p;
            dp[tmp]++;  
        }
        ans+=dp[0]+1ll*dp[0]*(dp[0]-1)/2;
        for(int i=1;i<=p-1;i++){
            ans+=1ll*(dp[i]-1)*dp[i]/2;
        }
    }
    cout<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/ttttttttrx/p/12439866.html