Portal

Description

给出\(n,m(n,m\leq10^9)\)和\(k(k\leq2000)\),求在\(k\)进制下,有多少个数值不同的纯循环小数可以表示成\(\dfrac{x}{y}\)的形式,其中\(x\in[1,n],y\in[1,m]\)。一个数是纯循环小数当且仅当它能写成\(a.\dot{c_1} c_2 c_3 \ldots c_{p-1}\dot{c_p}\)的形式。

Solution

原题相当于求有多少个数对\((x,y)\)满足\(gcd(x,y)=1\)且\(\dfrac{x}{y}\)是纯循环小数。因为若\(x,y\)不互质且在范围内,将\(\dfrac{x}{y}\)化为最简分数依然在范围内。

首先考虑一个数是纯循环小数意味着什么。

\[\begin{align*}
a.\dot{c_1} c_2 c_3 \ldots c_{p-1}\dot{c_p} &= a+\sum_{i=0}^{+∞}(0.c_1c_2c_3\ldots c_{p-1}c_p)_{k}\cdot k^{-ip} \\
&= a+(0.c_1c_2c_3\ldots c_{p-1}c_p)_{k}\sum_{i=0}^{+\infty}(k^{-p})^i \\
&= a+\frac{1}{1-k^{-p}}(0.c_1c_2c_3\ldots c_{p-1}c_p)_{k} \\
&= a+\frac{(c_1c_2c_3\ldots c_{p-1}c_p)_k}{k^p-1} \\
\frac{x}{y} &= a+\frac{(c_1c_2c_3\ldots c_{p-1}c_p)_k}{k^p-1} \\
\lfloor \frac{x}{y} \rfloor + \frac{x \bmod y}{y} &= a+\frac{(c_1c_2c_3\ldots c_{p-1}c_p)_k}{k^p-1}
\end{align*}$$ 令$a=\lfloor \dfrac{x}{y} \rfloor$,那么若$\dfrac{x \bmod y}{y}$能表示成$\dfrac{(c_1c_2c_3\ldots c_{p-1}c_p)_k}{k^p-1}$的形式则说明$\dfrac{x}{y}$是纯循环小数。由于$\dfrac{x \bmod y}{y}$是最简分数,所以$\dfrac{x}{y}$是纯循环小数 ⇔ $\exists p$使得$y|k^p-1$ ⇔ $\exists p$使得$k^p \bmod y = 1$ ⇔ $gcd(y,k)=1$。
于是原题相当于求
$$\begin{align*}
ans &= \sum_{x=1}^n \sum_{y=1}^n [gcd(x,y)=1][gcd(y,k)=1] \\
&= \sum_{d=1}^{+∞} \mu(d) \sum_{d|x}^n \sum_{d|y}^m [gcd(y,k)=1] \\
&= \sum_{d=1}^{+∞} \mu(d) \lfloor\frac{n}{d}\rfloor \sum_{i=1}^{\lfloor\frac{m}{d}\rfloor} [gcd(id,k)=1] \\
&= \sum_{d=1}^{min(n,m)} [gcd(d,k)=1]\mu(d) \lfloor\frac{n}{d}\rfloor \sum_{i=1}^{\lfloor\frac{m}{d}\rfloor} [gcd(i,k)=1] \\
\end{align*}$$于是我们发现我们主要要求两个东西:$f(x,k)=\sum_{i=1}^x [gcd(i,k)=1]$和$g(x,k)=\sum_{i=1}^x [gcd(i,k)=1]\mu(i)$。算出他们就可以利用整除分块来快速计算。
易知$f(x,k)=\lfloor\dfrac{x}{k}\rfloor f(k,k)+f(x\bmod k,k)$,而对于$x\in[0,k]$我们都可以预处理出来,所以$f$很好求。
考虑$g$怎么求。将$k$表示成$p^tq$的形式,其中$p$是质数,$gcd(p,q)=1$。那么$gcd(i,k)=1 ⇔ gcd(i,p)=1,gcd(i,q)=1$。那么我们从满足$gcd(i,q)=1$的$i$中减去$gcd(i,p)\neq1$即$p|i$的部分,即:
$$\begin{align*}
g(x,k) &= \sum_{i=1}^x[gcd(i,q)=1]\mu(i)-\sum_{p|i}^x[gcd(i,q)=1]\mu(i) \\
&= g(x,q)-\sum_{i=1}^{\lfloor\frac{x}{p}\rfloor}[gcd(ip,q)=1][gcd(i,p)=1]\mu(ip) \\
&= g(x,q)-\sum_{i=1}^{\lfloor\frac{x}{p}\rfloor}[gcd(i,k)=1]\mu(i)\mu(p) \\
&= g(x,q)-g(\lfloor\frac{x}{p}\rfloor,k)
\end{align*}$$ 易知$g(x,1)=\sum_{i=1}^x \mu(i)$,可以用杜教筛来求。用`map`或哈希表来对$g$进行存储以进行记忆化搜索,就可以通过本题啦。

##Code
```cpp
//「NOI2016」循环之美
#include <cstdio>
#include <map>
using namespace std;
const int N=3e6+10;
int n,m,k;
int gcd(int x,int y) {return x%y?gcd(y,x%y):y;}
int f0[2001];
void initF() {for(int i=1;i<=k;i++) f0[i]=f0[i-1]+(gcd(i,k)==1);}
int f(int x) {return x/k*f0[k]+f0[x%k];}
int prCnt,pr[N]; bool prNot[N];
int muS[N];
void initG(int n)
{
muS[1]=1;
for(int i=2;i<=n;i++)
{
if(!prNot[i]) pr[++prCnt]=i,muS[i]=-1;
for(int j=1;j<=prCnt;j++)
{
int x=i*pr[j]; if(x>n) break;
prNot[x]=true;
if(i%pr[j]) muS[x]=-muS[i]; else break;
}
}
for(int i=1;i<=n;i++) muS[i]+=muS[i-1];
}
map<pair<int,int>,int> g1;
map<pair<int,int>,bool> getG;
int sum(int x)
{
pair<int,int> x_1=make_pair(x,1);
if(x<=2e6) return g1[x_1]=muS[x];
if(getG[x_1]) return g1[x_1];
lint res=1;
for(int L=2,R;L<=x;L=R+1)
{
int v=x/L; R=x/v;
res-=1LL*(R-L+1)*sum(v);
}
getG[x_1]=true;
return g1[x_1]=res;
}
int g(int x,int k)
{
pair<int,int> x_k=make_pair(x,k);
if(getG[x_k]) return g1[x_k];
if(x==0||k==1) return sum(x);
int p,q;
for(int i=1;i<=prCnt;i++) if(k%pr[i]==0) {p=pr[i]; break;}
q=k; while(q%p==0) q/=p;
getG[x_k]=true;
int r=g(x,q)+g(x/p,k);
return g1[x_k]=r;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int n0=min(n,m);
initF(); initG(2e6);
long long ans=0;
for(int L=1,R;L<=n0;L=R+1)
{
int v1=n/L,v2=m/L; R=min(n/v1,m/v2);
ans+=1LL*(g(R,k)-g(L-1,k))*v1*f(v2);
}
printf("%lld\n",ans);
return 0;
}
```

##P.S.
本题中$n,m$的意义不等价,不可以互换...我以前为了简洁经常是用`swap`钦定$n<m$,结果这题鸽了一周看不出来锅...\]

LibreOJ2085 - 「NOI2016」循环之美的更多相关文章

  1. 「NOI2016」循环之美 解题报告

    「NOI2016」循环之美 对于小数\(\frac{a}{b}\),如果它在\(k\)进制下被统计,需要满足要求并且不重复. 不重复我们确保这个分数是最简分数即\((a,b)=1\) 满足要求需要满足 ...

  2. 「NOI2016」循环之美

    P1587 [NOI2016]循环之美 题目描述 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在 $k$ 进制下,一个数的小数部分是纯循环的,那么它就 ...

  3. *LOJ#2085. 「NOI2016」循环之美

    $n \leq 1e9,m \leq 1e9,k \leq 2000$,求$k$进制下$\frac{x}{y}$有多少种不同的纯循环数取值,$1 \leq x \leq n,1 \leq y \leq ...

  4. LOJ 2085: 洛谷 P1587: bzoj 4652: 「NOI2016」循环之美

    题目传送门:LOJ #2085. 两个月之前做的傻题,还是有必要补一下博客. 题意简述: 求分子为不超过 \(n\) 的正整数,分母为不超过 \(m\) 的正整数的所有互不相等的分数中,有多少在 \( ...

  5. 「NOI2016」循环之美(小性质+min_25筛)

    传送门. 题解 感觉这题最难的是第一个结论. x/y首先要互质,然后如果在10进制是纯循环小数,不难想到y不是2.5的倍数就好了. 因为十进制下除以2和5是除得尽的. 必然会多出来的什么东西. 如果是 ...

  6. 【LOJ】#2085. 「NOI2016」循环之美

    题解 我们要求的其实是这个东西= = \(\sum_{i = 1}^{n}\sum_{j = 1}^{n}[(i,j) == 1][(j,k) == 1]\) 然后变一下形 \(\sum_{j = 1 ...

  7. 「NOI2016」优秀的拆分 解题报告

    「NOI2016」优秀的拆分 这不是个SAM题,只是个LCP题目 95分的Hash很简单,枚举每个点为开头和末尾的AA串个数,然后乘一下之类的. 考虑怎么快速求"每个点为开头和末尾的AA串个 ...

  8. 「NOI2016」网格 解题报告

    「NOI2016」网格 容易注意到,答案最多为2,也就是说答案为-\(1,0,1,2\)四种,考虑逐个判断. 无解的情况比较简单 如果\(nm\le c+1\),显然无解 如果\(nm=c+2\),判 ...

  9. 「NOI2016」区间 解题报告

    「NOI2016」区间 最近思维好僵硬啊... 一上来就觉得先把区间拆成两个端点进行差分,然后扫描位置序列,在每个位置维护答案,用数据结构维护当前位置的区间序列,但是不会维护. 于是想研究性质,想到为 ...

随机推荐

  1. HDU - 5457 Hold Your Hand (Trie + 最小割)

    Hold Your Hand Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)T ...

  2. 使用ErrorProvider组件验证文本框输入

    实现效果: 知识运用: ErrorProvider组件的BlinkStyle属性 //指示错误图标的闪烁时间 public ErrorBlinkStyle BlinkStyle{ get;set; } ...

  3. orcle定时备份

    orcle定时备份 (1)写个.bat文件 例如: exp test/test@ORCL file=f:\back\test%date:~,%%date:~,%%date:~,%.dmp (2)开始, ...

  4. 使用struts2实现文件上传与下载功能

    这个问题做了两天,在网上找了很多例子,但是还有一些功能没有实现,暂时先把代码贴出来,以后在做这方面的功能时在修改 文件上传: 一开始我在网上找到基于servlet+jsp环境写的文件上传,但是在将页面 ...

  5. mysql绿色版下载及应用

    一.mysql绿色版下载 第一歩:打开下载网址:https://www.oracle.com 点击Menu-->Database and Technologies-->Databases- ...

  6. java从键盘输入三个整数,实现从小到大排序

    package study01; import java.util.Scanner; public class Sort { /** * 需求:由键盘输入三个整数分别存入变量a.b.c,对他们进行 排 ...

  7. eclipse 中main()函数中的String[] args如何使用?通过String[] args验证账号密码的登录类?静态的主方法怎样才能调用非static的方法——通过生成对象?在类中制作一个方法——能够修改对象的属性值?

    eclipse 中main()函数中的String[] args如何使用? 右击你的项目,选择run as中选择 run configuration,选择arguments总的program argu ...

  8. const,static,extern,#define

    一.const // 简单定义变量,可以修改变量的值 ; a = ; // const的用法 // 用法一: ; ; // 不允许修改,因为 const 修饰 b/c,指定 b/c 为常量!! // ...

  9. python爬虫基础18-Chrome调试前端工具

    01 Chrome调试 抓包工具原理 Chrome 开发者工具是一套内置在Google Chrome中Web开发和调试工具.使用开发者工具来重演,调试和剖析您的网站. 其中常用的有Elements(元 ...

  10. 用\r做出进度条

    在做ftp作业的时候,需要做一个上传和下载的进度条,做的时候发现用\r很容易就能做出来 def show_progress(self, has, total): rate = float(has) / ...