题目链接

BZOJ

题解

orz

此题太优美了

我们令\(\frac{x}{y}\)为最简分数,则\(x \perp y\)即,\(gcd(x,y) = 1\)

先不管\(k\)进制,我们知道\(10\)进制下如果\(\frac{x}{y}\)是纯循环的,只要\(2 \perp y\)且\(5 \perp y\)

可以猜想在\(k\)进制下同样成立

证明:

若\(\frac{x}{y}\)为纯循环小数,设其循环节长度为\(l\),那么一定满足

\[\{ \frac{xk^{l}}{y} \} = \{ \frac{x}{y}\}
\]

其中\(\{x\}\)指小数部分

可以写成

\[xk^{l}- \lfloor \frac{xk^{l}}{y} \rfloor * y= x - \lfloor \frac{x}{y} \rfloor * y
\]

可以看出就是同余的形式

\[xk^{l} \equiv x \pmod y
\]

由于\(x \perp y\)

\[k^{l} \equiv 1 \pmod y
\]

要使存在\(l\),使得式子成立,那么一定\(k \perp y\)

所以我们有

\[\begin{aligned}
ans &= \sum\limits_{i = 1}^{n} \sum\limits_{j = 1}^{m} [i \perp j] [j \perp k] \\
&= \sum\limits_{j = 1}^{m} [j \perp k] \sum\limits_{i = 1}^{n} [(i,j) == 1] \\
&= \sum\limits_{j = 1}^{m} [j \perp k] \sum\limits_{i = 1}^{n} \epsilon((i,j)) \\
&= \sum\limits_{j = 1}^{m} [j \perp k] \sum\limits_{i = 1}^{n} \sum\limits_{d|(i,j)} \mu(d) \\
&= \sum\limits_{d = 1}^{n} \mu(d) \sum\limits_{d|i}^{n} \sum\limits_{d|j}^{m} [j \perp k] \\
&= \sum\limits_{d = 1}^{n} [d \perp k] \mu(d) \lfloor \frac{n}{d} \rfloor \sum\limits_{j}^{\lfloor \frac{m}{d} \rfloor} [j \perp k] \\
\end{aligned}
\]

我们令

\[f(n) = \sum\limits_{i}^{n} [i \perp k]
\]

根据\(gcd(i + k,k) = gcd(i,k)\),我们有

\[f(n) = \lfloor \frac{n}{k} \rfloor f(k) + f(n \mod k)
\]

所以我们只需要\(O(klogk)\)暴力计算\(f(1....k)\)就可以\(O(1)\)计算后面的式子了

现在考虑前面的

\[\sum\limits_{d = 1}^{n} [d \perp k] \mu(d)
\]

为了使能整除分块,我们必须算出其前缀和

令

\[g(n,k) = \sum\limits_{i = 1}^{n} [i \perp k] \mu(d)
\]

用类似上面同样的方法:

\[\begin{aligned}
g(n,k) &= \sum\limits_{i = 1}^{n} [i \perp k] \mu(i) \\
&= \sum\limits_{i = 1}^{n} \mu(i) \sum\limits_{d|i,d|k} \mu(d) \\
&= \sum\limits_{d | k} \mu(d) \sum\limits_{d|i} \mu(i) \\
&= \sum\limits_{d | k} \mu(d) \sum\limits_{i = 1}^{\lfloor \frac{n}{d} \rfloor} \mu(id) \\
&= \sum\limits_{d | k} \mu(d) \sum\limits_{i = 1}^{\lfloor \frac{n}{d} \rfloor} [i \perp d]\mu(i) * \mu(d) \\
&= \sum\limits_{d | k} \mu(d)^2 \sum\limits_{i = 1}^{\lfloor \frac{n}{d} \rfloor} [i \perp d]\mu(i) \\
&= \sum\limits_{d | k} \mu(d)^2 g(\lfloor \frac{n}{d} \rfloor,d) \\
\end{aligned}
\]

就可以递归求解

当\(n = 0\)时,\(g(0,k) = 0\)

当\(k = 1\)时,\(g(n,1) = \sum\limits_{i = 1}^{n} \mu(i)\),上杜教筛即可

因为\(\lfloor \frac{n}{d} \rfloor\)只有\(\sqrt{n}\)种取值,\(d\)只能取\(k\)的因子,记其数量为\(p\)

那么求\(g(n,k)\)总的复杂度为\(O(p\sqrt{n} + n^{\frac{2}{3}})\)

于是乎我们就解决这道题了

总复杂度\(O(p\sqrt{n} + n^{\frac{2}{3}} + \sqrt{n} + klogk)\)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
#define mp(a,b) make_pair<LL,LL>(a,b)
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000;
map<LL,LL> _mu;
map<LL,LL>::iterator it;
map<pair<LL,LL>,LL> G;
map<pair<LL,LL>,LL>::iterator IT;
int N;
int p[maxn],pi,isn[maxn];
LL Smu[maxn],f[maxn],mu[maxn];
LL n,m,K;
int gcd(int a,int b){return b ? gcd(b,a % b) : a;}
void init(){
N = 1000000;
mu[1] = 1;
for (int i = 2; i <= N; i++){
if (!isn[i]) p[++pi] = i,mu[i] = -1;
for (int j = 1; j <= pi && i * p[j] <= N; j++){
isn[i * p[j]] = true;
if (i % p[j] == 0){
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
for (int i = 1; i <= N; i++) Smu[i] = Smu[i - 1] + mu[i];
for (int i = 1; i <= K; i++) f[i] = f[i - 1] + (gcd(i,K) == 1);
}
LL S(LL n){
if (n <= N) return Smu[n];
if ((it = _mu.find(n)) != _mu.end()) return it->second;
LL ans = 1;
for (LL i = 2,nxt; i <= n; i = nxt + 1){
nxt = n / (n / i);
ans -= (nxt - i + 1) * S(n / i);
}
return _mu[n] = ans;
}
LL F(LL n){
return (n / K) * f[K] + f[n % K];
}
LL g(LL n,LL k){
if ((IT = G.find(mp(n,k))) != G.end())
return IT->second;
if (n == 0) return 0;
if (k == 1) return S(n);
LL ans = 0;
for (LL i = 1; i * i <= k; i++){
if (k % i == 0){
if (mu[i]) ans += g(n / i,i);
if (i * i != k && mu[k / i])
ans += g(n / (k / i),k / i);
}
}
return G[mp(n,k)] = ans;
}
int main(){
cin >> n >> m >> K;
init();
LL ans = 0,now,last = 0;
for (LL i = 1,nxt; i <= min(n,m); i = nxt + 1){
nxt = min(n / (n / i),m / (m / i));
now = g(nxt,K);
ans += 1ll * (now - last) * (n / i) * F(m / i);
last = now;
}
cout << ans << endl;
return 0;
}

BZOJ4652 [Noi2016]循环之美 【数论 + 莫比乌斯反演 + 杜教筛】的更多相关文章

  1. BZOJ4652 NOI2016循环之美(莫比乌斯反演+杜教筛)

    因为要求数值不同,不妨设gcd(x,y)=1.由提示可以知道,x/y是纯循环小数的充要条件是x·klen=x(mod y).因为x和y互质,两边同除x,得klen=1(mod y).那么当且仅当k和y ...

  2. 【bzoj4176】Lucas的数论 莫比乌斯反演+杜教筛

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  3. BZOJ 4176 Lucas的数论 莫比乌斯反演+杜教筛

    题意概述:求,n<=10^9,其中d(n)表示n的约数个数. 分析: 首先想要快速计算上面的柿子就要先把d(ij)表示出来,有个神奇的结论: 证明:当且仅当a,b没有相同的质因数的时候我们统计其 ...

  4. [复习]莫比乌斯反演,杜教筛,min_25筛

    [复习]莫比乌斯反演,杜教筛,min_25筛 莫比乌斯反演 做题的时候的常用形式: \[\begin{aligned}g(n)&=\sum_{n|d}f(d)\\f(n)&=\sum_ ...

  5. [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛) 题面 我们知道,从区间\([L,R]\)(L和R为整数)中选取N个整数,总共有\((R-L+1)^N\)种方案.求最大公约数 ...

  6. 【bzoj3930】[CQOI2015]选数 莫比乌斯反演+杜教筛

    题目描述 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一 ...

  7. [NOI2016]循环之美——结论+莫比乌斯反演

    原题链接 好妙的一道神仙题 题目大意 让你求在\(k\)进制下,\(\frac{x}{y}\)(\(x\in [1,n],y\in [1,m]\))中有多少个最简分数是纯循环小数 SOLUTION 首 ...

  8. NOI 2016 循环之美 (莫比乌斯反演+杜教筛)

    题目大意:略 洛谷传送门 鉴于洛谷最近总崩,附上良心LOJ链接 任何形容词也不够赞美这一道神题 $\sum\limits_{i=1}^{N}\sum\limits_{j=1}^{M}[gcd(i,j) ...

  9. 【CCPC-Wannafly Winter Camp Day3 (Div1) F】小清新数论(莫比乌斯反演+杜教筛)

    点此看题面 大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\). 莫比乌斯反演 这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有) 关于莫比乌 ...

随机推荐

  1. 《JSON笔记之二》----封装JSONUtil

    许多java开发人员对于fastjson再也熟悉不过了,这是alibaba开源的依赖,使用fastjson可以使我们很容易的把请求json串转换成为我们所需要的对象.list.map等对象格式,对于开 ...

  2. linux shell 部分问题解决方法

    1.  判断shell里判断字符串是否包含某个字符 a.  可以用正则式匹配符号      “=~” 举例:str="this is a string" 要想在判断str中是否含有 ...

  3. Ansible学习 Patterns

    Ansible中ad-hoc命令格式如下:ansible <pattern_goes_here> -m <module_name> -a <arguments>,P ...

  4. PHP continue和break的用法(深入理解)

    对于刚入门的PHP童鞋们来说,在循环体中的continue和break的作用总是分不清到底是什么意思, 怎么用, 两者到底有什么区别? 接下来说几个例子,其实它们是很好区分的. <?php $t ...

  5. 数据库中where与having的区别

    从整体声明角度分析: “where”是一个约束声明,在查询数据库结果返回之前对数据库的查询条件做一个约束,即返回结果之前起作用,“where”后面不能跟聚合函数: “having”是一个过滤声明,在查 ...

  6. tomcat 无论如何都无法创建新的Servers

    1.退出eclipse 2.到[工程目录下 workspace ]/.metadata/.plugins/org.eclipse.core.runtime 3.把org.eclipse.wst.ser ...

  7. PAT (Basic Level) Practice 1040 有几个PAT

    个人练习 字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位( ...

  8. POJ:2739-Sum of Consecutive Prime Numbers(尺取)

    Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27853 Ac ...

  9. Leetcode 701. 二叉搜索树中的插入操作

    题目链接 https://leetcode.com/problems/insert-into-a-binary-search-tree/description/ 题目描述 给定二叉搜索树(BST)的根 ...

  10. interface in iOS

    lo = localhosten = ethernetap = Probably for access point (if you are acting as a wifi host) pdp_ip ...