题意
已知序列AAA为1,11,111,1111,...1,11,111,1111,...1,11,111,1111,...,求
∑i=1n∑j=1m[A(ij)%p==0]\sum_{i=1}^n\sum_{j=1}^m[A(i^j)\%p==0]i=1∑nj=1∑m[A(ij)%p==0]
思路
易知A(n)=10n−19A(n)=\frac{10^n-1}{9}A(n)=910n−1,那么有
∑i=1n∑j=1m[10ij−19%p==0]\sum_{i=1}^n\sum_{j=1}^m[\frac{10^{i^j}-1}{9}\%p==0]i=1∑nj=1∑m[910ij−1%p==0]
考虑10n−19\frac{10^n-1}{9}910n−1和ppp的关系,先考虑999和ppp互质,那么可以变为
(10n−1)⋅inv9 %p==0(10^n-1)\cdot inv9\ \% p==0(10n−1)⋅inv9 %p==0
由于互质inv9≠0inv9\neq0inv9̸=0,所以只有
10n−1 %p==010^n-1\ \% p==010n−1 %p==0
即
10n≡1(mod p)10^n\equiv 1 (mod\ p)10n≡1(mod p)
根据费马小定理,101010和ppp互质有
10phi(p)≡1(mod p)10^{phi(p)}\equiv 1(mod\ p)10phi(p)≡1(mod p)
10p−1≡1(mod p)10^{p-1}\equiv 1(mod\ p)10p−1≡1(mod p)
由于100≡1(mod p)10^0\equiv 1(mod\ p)100≡1(mod p),那么循环节至少为p−1p-1p−1,考虑是否有更小的循环节,根据同余式的性质
a≡b(mod p)→an≡bn(mod p)a\equiv b(mod\ p)\rightarrow a^n\equiv b^n(mod\ p)a≡b(mod p)→an≡bn(mod p)
那么令ddd为p−1p-1p−1的因子,即d∣p−1d|p-1d∣p−1,最小的循环节可能为ddd
(10d)p−1d≡1(mod p)(10^{d})^{\frac{p-1}{d}}\equiv 1(mod\ p)(10d)dp−1≡1(mod p)
所以我们可以对p−1p-1p−1的因子进行检验得到最小的循环节ddd,找到了最小的循环节ddd之后我们如何求解答案呢。由于循环节为ddd,所以iji^jij必须是ddd的倍数。考虑jjj是固定的,那么只要iii含有d⌈1j⌉d^{\left \lceil \frac{1}{j} \right \rceil}d⌈j1⌉的因子就可以了,令g=d⌈1j⌉g=d^{\left \lceil \frac{1}{j} \right \rceil}g=d⌈j1⌉,那么1∼n1\sim n1∼n中是ggg的倍数的个数为ng\frac{n}{g}gn。再考虑ggg,我们可以将ddd唯一分解了,那么就有
d=p1a1p2a2p3a3⋯pkakd=p_1^{a_1}p_2^{a_2}p_3^{a_3}\cdots p_k^{a_k}d=p1a1p2a2p3a3⋯pkak
ggg就有
g=p1⌈a1j⌉p2⌈a2j⌉p3⌈a3j⌉⋯pk⌈akj⌉g=p_1^{\left \lceil \frac{a_1}{j} \right \rceil}p_2^{\left \lceil \frac{a_2}{j} \right \rceil}p_3^{\left \lceil \frac{a_3}{j} \right \rceil}\cdots p_k^{\left \lceil \frac{a_k}{j} \right \rceil}g=p1⌈ja1⌉p2⌈ja2⌉p3⌈ja3⌉⋯pk⌈jak⌉
随着jjj的变化,ggg的值也是变化的,设maxn=max{a1,a2,a3,⋯ ,ak}maxn=max\{a_1,a_2,a_3,\cdots,a_k\}maxn=max{a1,a2,a3,⋯,ak},当jjj的值为1∼maxn1\sim maxn1∼maxn时ggg也就是随着变化的,我们分别计算每一个的贡献为ng\frac{n}{g}gn,当j>maxnj>maxnj>maxn时ggg将不再变化贡献就为ng(m−maxn)\frac{n}{g}(m-maxn)gn(m−maxn)
这样就能统计出答案了,但是当p=2,p=5p=2,p=5p=2,p=5时,虽然999和ppp互质但是10n%p==010^n\% p==010n%p==0,所以明显的答案都为000
第二我们考虑p=3p=3p=3的情况,由于p=3p=3p=3于分母999并不互质,所以我们并不能像上面那么做。考虑
∑i=1n∑j=1m[A(ij)%3==0]\sum_{i=1}^n\sum_{j=1}^m[A(i^j)\%3==0]i=1∑nj=1∑m[A(ij)%3==0]
由于A(ij)A(i^j)A(ij)为长度为iji^jij连续的111的整数,一个整数是否能被333整除我们知道就是把各位上的数字加起来是333的倍数就能整除了,令A(i)A(i)A(i)每一位上的和为SSS,那么A(ij)A(i^j)A(ij)每一位上的和就为j×Sj\times Sj×S,由于AAA上的每一位都是111,所以S=iS=iS=i,故最后的答案就是n/3∗mn/3*mn/3∗m
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
long long quickmod(long long a,long long b,long long mod=1e9+7)
{
long long ans=1;
while(b)
{
if(b%2==1)
ans=ans*a%mod;
b=b/2;
a=a*a%mod;
}
return ans;
}
pair<int,int>a[1005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long p,n,m;
scanf("%lld%lld%lld",&p,&n,&m);
if(p==2||p==5)
{
printf("0\n");
continue;
}
else if(p==3)
{
printf("%lld\n",n/3*m);
continue;
}
long long x=p-1;
int minn=p-1;
for(int i=2; i*i<=x; i++)
{
if(x%i==0)
{
if(quickmod(10,i,p)==1)
minn=min(minn,i);
if(quickmod(10,x/i,p)==1)
minn=min(1ll*minn,x/i);
}
}
int cnt=0;
int maxn=0;
x=minn;
for(int i=2; i*i<=x; i++)
{
if(x%i==0)
{
a[cnt].first=0;
a[cnt].second=0;
a[cnt].first=i;
while(x%i==0)
{
a[cnt].second++;
x=x/i;
}
maxn=max(a[cnt].second,maxn);
cnt++;
}
}
if(x>1)
{
a[cnt].first=0;
a[cnt].second=0;
a[cnt].first=x;
a[cnt].second++;
maxn=max(a[cnt].second,maxn);
cnt++;
}
long long ans=0;
long long g=1;
for(int j=1; j<=min(1ll*maxn,m); j++)
{
g=1;
for(int i=0; i<cnt; i++)
{
g=g*quickmod(a[i].first,ceil(1.0*a[i].second/j));
}
ans+=n/g;
}
if(m>maxn)
ans+=n/g*(m-maxn);
printf("%lld\n",ans);
}
return 0;
}
本文探讨了模数运算在序列求和中的应用,通过分析序列AAA与模数p的关系,利用费马小定理和循环节的概念,解决了特定序列求和问题。针对不同模数情况,如p=3时的特殊处理,提供了详细的算法实现。
940

被折叠的 条评论
为什么被折叠?



