$n \leq 1e9,m \leq 1e9,k \leq 2000$,求$k$进制下$\frac{x}{y}$有多少种不同的纯循环数取值,$1 \leq x \leq n,1 \leq y \leq m$。纯循环数是指小数点后直接就开始循环,整数也算。

与上个题的丑陋相比这个题不知道美到哪里去。。虽然自己没想出来。

提示说了,出现相同余数时有纯循环。假设循环节是$l$,那么$xk^l$和$x$除$y$会得到相同余数--同余!$xk^l \equiv x (\mod y)$。由于题目要互不相同的,所以$x$和$y$互质,有逆元。两边同乘$x$的逆元,得$k^l \equiv 1 (\mod y)$,存在这样的$l$,由欧拉定理得只需$k$与$y$互质即可。可以开始推式子。

$\\ \sum_{x=1}^{n}\sum_{y=1}^m[(x,y)=1][(k,y)=1]$
$\\ =\sum_{y=1}^{m}[(k,y)=1]\sum_{x=1}^{n}[(x,y)=1]$
$\\ =\sum_{y=1}^{m}[(k,y)=1]\sum_{x=1}^{n}\sum_{d|x,d|y}\mu(d)$
$\\ =\sum_{y=1}^{m}[(k,y)=1]\sum_{d|y}\mu(d)\left \lfloor \frac{n}{d} \right \rfloor$
$\\ =\sum_{d=1}^{m}\mu(d)\left \lfloor \frac{n}{d} \right \rfloor\sum_{d|y,y \leq m}[(k,y)=1]$
$\\ =\sum_{d=1}^{m}\mu(d)\left \lfloor \frac{n}{d} \right \rfloor\sum_{i=1}^{\left \lfloor \frac{m}{d} \right \rfloor}[(k,i)=1][(k,d)=1]$
$\\ =\sum_{d=1}^{min(n,m)}\mu(d)\left \lfloor \frac{n}{d} \right \rfloor[(k,d)=1]\sum_{i=1}^{\left \lfloor \frac{m}{d} \right \rfloor}[(k,i)=1]$

可以发现$f(t)=\sum_{i=1}^t[(k,i)=1]=\left \lfloor \frac{t}{k} \right \rfloor f(k)+f(t \mod k)$。这样就可以O(1)算后面那坨,在min(n,m)的时间内得到84分。

 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 //#include<math.h>
 5 //#include<set>
 6 //#include<queue>
 7 //#include<bitset>
 8 //#include<vector>
 9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12 
13 #define LL long long
14 int qread()
15 {
16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
18 }
19 
20 //Pay attention to '-' , LL and double of qread!!!!
21 
22 int n,m,K;
23 int f[2011];
24 
25 #define maxm 20000011
26 int miu[maxm],prime[maxm],lp=0; bool notprime[maxm];
27 void pre(int n)
28 {
29     miu[1]=1;
30     for (int i=2;i<=n;i++)
31     {
32         if (!notprime[i]) {prime[++lp]=i; miu[i]=-1;}
33         for (int tmp,j=1;j<=lp && 1ll*i*prime[j]<=n;j++)
34         {
35             notprime[tmp=i*prime[j]]=1;
36             if (i%prime[j]) miu[tmp]=-miu[i];
37             else {miu[tmp]=0; break;}
38         }
39     }
40 }
41 
42 int gcd(int a,int b) {while (b^=a^=b^=a%=b); return a;}
43 int getf(int x) {return x/K*f[K]+f[x%K];}
44 
45 int main()
46 {
47     n=qread(); m=qread(); K=qread();
48     for (int i=1;i<=K;i++) f[i]=f[i-1]+(gcd(i,K)==1);
49     pre(min(n,m));
50     LL ans=0;
51     for (int i=1,to=min(n,m);i<=to;i++) if ((i%K>0) && (f[i%K]-f[(i-1)%K])>0)
52         ans+=miu[i]*(n/i)*1ll*getf(m/i);
53     printf("%lld\n",ans);
54     return 0;
55 }
View Code

相关文章:

  • 2021-07-02
  • 2022-02-16
  • 2021-10-13
  • 2021-12-03
  • 2021-05-19
  • 2021-08-06
  • 2021-10-03
  • 2022-12-23
猜你喜欢
  • 2021-10-15
  • 2021-06-22
  • 2021-12-27
  • 2021-09-05
  • 2022-01-14
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案