Description

题库链接

给出十进制下的 \(n,m,k\) ,求 \(\frac{i}{j},i\in[1,n],j\in[1,m]\) 在 \(k\) 进制下不同的纯循环小数个数。

纯循环小数定义为该数小数点后全部都是循环节。

\(1\leq n,m\leq 10^9,1\leq k\leq 2000\)

Solution

首先考虑怎样的 \(\frac{x}{y}\) 会满足“纯循环”小数。

比较显然的是(题目中给出了提示)只要 \(\exists a\in\mathbb{N^*}\)

\[\begin{aligned}x&\equiv x\cdot k^a&\pmod{y}\\1&\equiv k^a&\pmod{y}\end{aligned}\]

即 \(\gcd(k^a,y)=1\Rightarrow \gcd(k,y)=1\) 。

那么现在式子就变成求

\[\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=1][\gcd(j,k)=1]\]

我们先把奇奇怪怪的东西丢一边,依照套路

\[\begin{aligned}\Rightarrow &\sum_{i=1}^n\sum_{j=1}^m\sum_{d\mid \gcd(i,j)}\mu(d)[\gcd(j,k)=1]\\=&\sum_{d=1}^{\min\{n,m\}}\mu(d)\left\lfloor\frac{n}{d}\right\rfloor\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[\gcd(jd,k)=1]\end{aligned}\]

由于 \(\gcd(jd,k)=1\Leftrightarrow \gcd(j,k)=1\wedge\gcd(d,k)=1\) ,那么

\[\Rightarrow \sum_{d=1}^{\min\{n,m\}}[\gcd(d,k)=1]\mu(d)\left\lfloor\frac{n}{d}\right\rfloor\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[\gcd(j,k)=1]\]

不妨记 \(\sum\limits_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[\gcd(j,k)=1]=F\left(\left\lfloor\frac{m}{d}\right\rfloor\right)\) ,注意到 \(\gcd(j,k)=\gcd(j-k,k)\) ,那么这个 \(F\) 很好求

\[F(n)=\left\lfloor\frac{n}{k}\right\rfloor f(k)+f(n\bmod{k})\]

其中 \(f(n)\) 表示 \(\sum\limits_{j=1}^{\min\{n,k\}}[\gcd(j,k)=1]\) 。这个可以 \(O(k\log(k))\) 预处理出来。 \(O(1)\) 回答询问。

那么原式变成

\[\sum_{d=1}^{\min\{n,m\}}\left\lfloor\frac{n}{d}\right\rfloor F\left(\left\lfloor\frac{m}{d}\right\rfloor\right)[\gcd(d,k)=1]\mu(d)\]

记 \([\gcd(d,k)=1]\mu(d)=g(d)\) ,考虑如何求 \(g(d)\) 。

这里比较巧妙,我们假设 \(M(n)=\sum\limits_{i=1}^n \mu(i)\) 。可以得到

\[\begin{aligned}g(n)&=M(n)-\sum_{i=2}^{\min\{k,n\}}[i\mid k]\sum_{j=1}^{\left\lfloor\frac{n}{d}\right\rfloor}[\gcd(j,k)=1]\mu(ji)\\&=M(n)-\sum_{i=2}^{\min\{k,n\}}[i\mid k]\mu(i)\sum_{j=1}^{\left\lfloor\frac{n}{d}\right\rfloor}[\gcd(j,k)=1]\mu(j)\\&=M(n)-\sum_{i=2}^{\min\{k,n\}}[i\mid k]\mu(i)g(\left\lfloor\frac{n}{d}\right\rfloor)\end{aligned}\]

那么可以枚举 \(k\) 的因数类似于杜教筛来求解。

复杂度为 \(O\left(n^{\frac{2}{3}}+\sigma_0(k)\sqrt{n}\right)\) 。

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 233333+5; int n, m, k, mu[N], prime[N], isprime[N], tot;
map<int, ll>mmu, mg; ll ans;
int f[N], sum[N], g[N], factor[N], cnt; int gcd(int a, int b) {return b ? gcd(b, a%b) : a; }
void get() {
memset(isprime, 1, sizeof(isprime));
isprime[1] = 0; mu[1] = g[1] = sum[1] = 1;
for (int i = 2; i < N; i++) {
if (isprime[i]) mu[prime[++tot] = i] = -1;
for (int j = 1; j <= tot && i*prime[j] < N; j++) {
if (i%prime[j]) mu[i*prime[j]] = -mu[i];
isprime[i*prime[j]] = 0;
if (i%prime[j] == 0) break;
}
sum[i] = sum[i-1]+mu[i]; g[i] = g[i-1];
if (gcd(i, k) == 1) g[i] += mu[i];
}
for (int i = 1; i <= k; i++) {
f[i] = f[i-1]; if (gcd(i, k) == 1) ++f[i];
if (k%i == 0 && i != 1) factor[++cnt] = i;
}
} ll gmu(int x) {
if (x < N) return sum[x];
if (mmu.count(x)) return mmu[x];
ll ans = 1;
for (int last, i = 2; i <= x; i = last+1) {
last = x/(x/i);
ans -= 1ll*(last-i+1)*gmu(x/i);
}
return mmu[x] = ans;
}
ll gg(int x) {
if (x < N) return g[x];
if (mg.count(x)) return mg[x];
ll ans = gmu(x);
for (int i = 1; i <= cnt && factor[i] <= x; i++)
ans -= 1ll*mu[factor[i]]*gg(x/factor[i]);
return mg[x] = ans;
}
ll F(int x) {return 1ll*x/k*f[k]+f[x%k]; }
void work() {
scanf("%d%d%d", &n, &m, &k); get();
for (int last, i = 1; i <= min(n, m); i = last+1) {
last = min(n/(n/i), m/(m/i));
ans += 1ll*F(m/i)*(n/i)*(gg(last)-gg(i-1));
}
printf("%lld\n", ans);
}
int main() {work(); return 0; }

最新文章

  1. 通过自定义相册来介绍photo library的使用
  2. Aggregate
  3. hdu 4055 &amp;&amp; hdu 4489 动态规划
  4. 使用Objective-C的文档生成工具
  5. 6.css文本样式
  6. 关于javascript的window.onscroll方法
  7. 【CSS3】Advanced4:Advanced Colors
  8. Java 之文件目录操作
  9. javascript数据类型、初始化
  10. 洛谷教主花园dp
  11. DUBBO报错分析—1(连接zookeeper成功,调用方法无反应,不报错)
  12. Linux自定义分隔符IFS引发的文本处理问题
  13. 一步一步教你如何用Python做词云
  14. C语言编程常见技巧(问题???)
  15. 周刷题第二期总结(Longest Substring Without Repeating Characters and Median of Two Sorted Arrays)
  16. Java_常用工具类收集
  17. Runable和Thread
  18. Linux(CentOS)下同时启动两个tomcat
  19. 一些说明&amp;其他奇奇怪怪的东西
  20. Spring 4 官方文档学习(十)数据访问之ORM

热门文章

  1. shell 命令 netstat 查看端口占用
  2. 第一天:html+JavaScript函数
  3. Android-Could not find method implementation() for arguments
  4. Android GridView 滑动条设置一直显示状态
  5. [转载]WIKI MVC模式
  6. DFS遍历中forward、backward以及cross边的界定
  7. 统计--VARCHAR与NVARCHAR在统计预估上的区别
  8. C#单例类的实现
  9. 背水一战 Windows 10 (48) - 控件(集合类): FlipView
  10. Spring IOC 容器源码分析 - 余下的初始化工作