时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
For little pupils, a very large number usually means an integer with many many digits. Let’s define a class of big integers which consists only of the digit one(11⋯1). The first few integers in this class are 1,11,111,1111⋯. Denote A(n) as the n-th smallest integer in this class. To make it even larger, we consider integers in the form of A(a^ b). Now, given a prime number p, how many pairs (i,j) are there such that 1 ≤ i ≤ n,1 ≤ j ≤m, A(i^j) ≡0(mod p)
The input contains multiple cases. The first line of the input contains a single integer T (1≤T≤100), the number of cases.
For each case, the input consists of a single line, which contains 3 positive integers p, n, m (p, n, m ≤ 10 e 9) .
Print the answer, a single integer, in one separate line for each case.
-----------------------------------------------------------分隔线----------------------------------------------------------------
1 ≤ i ≤ n, 1 ≤ j ≤ m 有多少种情况满足i ^ j个1能被p整除。
原式:A(i ^ j) % p==0(记i ^ j为n)
易知,A(n)等价于(10 ^ n-1)/9,即为n个1。可化简为:((10^n-1)/9)%p ==0。
因为p为质数,所以9与p互质,故((10^n-1)*inv9)%p ==0。
因为inv9!=0,故(10^n-1)%p ==0,即(10 ^ n)≡1(mod p)。
根据费马小定理,10与p互质,故10 ^ phi( p)≡1(mod p)。
因为p为素数,phi(p )==p-1,所以10 ^ (p-1)≡1(mod p)。
所以最小循环节d必定是p-1的因数。然后直接O(sqrt(p-1))暴力找到d。
(最后一点懒得写了,直接贴牛客的题解了)
------------------------------------分割线---------------------------------------------------------------------------------------
#include
#define min(x,y) (x>y?y:x)
#define __bug(x) cout<<"---test:"<>=1;
}
return ret%p;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll p,n,m;
scanf("%lld%lld%lld",&p,&n,&m);
if(p==2||p==5)
{
printf("0\n");
continue;
}
if(p==3)
{
printf("%lld\n",n/3*m);
continue;
}
ll d=p-1;
for(int i=2;i*i<=p-1;i++)
{
if((p-1)%i==0)
{
if(quick_pow(10,i,p)==1)
{
d=min(d,i);
}
if(quick_pow(10,(p-1)/i,p)==1)
{
d=min(d,(p-1)/i);
}
}
}
// __bug(d);
int cnt=0;
ll dd=d;
ll maxn=0;
for(int i=2;i*i<=d;i++)
{
if(dd%i==0)
{
pr[cnt].num=i;
pr[cnt].times=0;
while(dd%i==0)
{
dd/=i;
pr[cnt].times++;
}
maxn=max(maxn,pr[cnt].times);
cnt++;
// __bug(maxn);
}
}
ll g=1;
if(dd>1)
{
pr[cnt].num=dd;
pr[cnt].times=1;
maxn=max(pr[cnt].times,maxn);
cnt++;
// __bug(maxn);
}
// for(int i=0;imaxn)
{
ans+=n/g*(m-maxn);
}
printf("%lld\n",ans);
}
return 0;
}