Gym-100814K 数位DP 模拟除法

Johnny is a brilliant mathematics student. He loves mathematics since he was a child, now he is working on his PhD thesis. He faces a small mathematical problem, he has a n digit integer number (let us call it s) , he wants to find how many substring of s are divisible by a prime number p.

His supervisor professor is on vacation now, so can you play his role and help him with that?

https://cn.vjudge.net/contest/174050#problem/K

#include <bits/stdc++.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 30000000
#define MOD 1000000007
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define pai pair<int,int>
#define ref(i,x,y)for(int i=x;i<=y;++i)
#define def(i,x,y)for(int i=x;i>=y;--i)
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pai1;
const double EPS=1e-8;
const double PI=acos(-1);
//next_permutation
int T,n,p,number[1000001],s[1000001],t[201];
unsigned long long a,b;
int main()
{
    scanf("%d",&T);
    ref(i,1,T)
    {
                //freopen("input.txt","r",stdin);
                //freopen("out.txt","w",stdout);
        cin>> a >> b >> n >> p;
        ref(i,1,n)
        {
            number[i]=a*10/b;
            a=a*10;
            a%=b;
        }
        if(p==2||p==5||p==10)
        {
            long long ans=0;
            ref(i,1,n)if(number[i]%p==0)ans+=i;
            cout<< ans<< endl;
            continue;
        }
        int tmp=1;
        s[n+1]=0;
        def(i,n,1)
        {
            s[i]=(s[i+1]+tmp*number[i])%p;
            tmp=tmp*10%p;
        }
        ref(i,0,p)t[i]=0;
        def(i,n+1,1)t[s[i]]++;
        long long ans=0;
        ref(i,0,p-1)
        if(t[i]>1)ans+=1LL*t[i]*(t[i]-1)/2;
        cout<< ans<< endl;
    }
}

 

posted @ 2017-09-20 23:57  Aragaki  阅读(330)  评论(0编辑  收藏  举报