2019牛客暑期多校训练营(第三场) D Big Integer(数论)

题目链接:https://ac.nowcoder.com/acm/contest/883/D

 

题目大意:定义f(n)=n个1组成的十进制数,如f(3)=111,给出n和m,求1~n中取i,1~m中取j,f(i^{j})\equiv 0(mod p)有几对

 

题目思路:首先当p为2和5的时候可以发现无论如何它都没法mod p得到0,所以直接输出0就好。

为书写方便,这里定义n=i^{j}

f(n)=\frac{10^{n}-1}{9}

所以原式等价于求\frac{10^{n}-1}{9}=0(mod p)

=(10^{n}-1)*inv(9)=0(modp)

在p为3的情况下,由于3和9不互质,9没有逆元,所以3需要另外算,3的倍数就是所有位上的和需要是3的倍数,由于本题每一位都是3,所以就是求i^{j}是3的倍数的种类数,那就要求i是3的倍数,这种i共有n/3种,每种都可以跟任意一个j合作符合要求,也就是n/3*m

其他情况继续讨论,由于inv(9)不等于0

所以10^{n}-1=0(mod)p

10^{n}=1(mod p)

2和5已经刚才讨论过,剩下的全是跟10互质的p

那么由费马小定理or欧拉定理均可以得知

10^{p-1}=1(modp)

也就是循环节最大也就p-1了,如果想变小的话,很明显得要是它的因数,所以直接sqrt(n)枚举因数看看最小的循环节是谁。

找到最小循环节以后,假设它是x,那么它分解质因数以后得到的会是x=p_{1}^{a_{1}}p_{2}^{a_{2}}p_{3}^{a_{3}}...

对于最小的质数2,当指数为30时就已经超过了1e9,所以a不会大于30,如果大于的话直接当30算就行,因为只要temp拥有x的每一个质因子且数量大于等于x的相应数量就行。

所以对于每个j来说,最小的那个符合要求的数字得拥有x的每一个质因子且数量大于等于x的相应数量,直接a1/j向上取整就行,然后找出n里有多少个这种符合要求的数字的倍数,本题就结束了

 

以下是代码:

#include
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define per(i,a,b) for(ll i=a;i>=b;i--)
#define ll long long
const ll MAXN = 5e5+5;
const ll MOD = 1e9+7;
ll powmod(ll x,ll y,ll MOD){
    ll rst=1;
    for(;y;y>>=1){
        if(y&1)rst=rst*x%MOD;
        x=x*x%MOD;
    }
    return rst;
}
ll a[MAXN],num[MAXN];
int main()
{
    ll t,p,n,m;
    scanf("%lld",&t);
    while(t--){
        memset(num,0,sizeof(num));
        scanf("%lld%lld%lld",&p,&n,&m);
        if(p==2||p==5){cout<<0<

 

你可能感兴趣的:(数论)