UOJ #221 【NOI2016】 循环之美
题目链接:循环之美
这道题感觉非常优美……能有一个这么优美的题面和较高的思维难度真的不容易……
为了表示方便,让我先讲一下两个符号。\([a]\)表示如果\(a\)为真,那么返回\(1\),否则返回\(0\); \(a \perp b\)表示\(a\)与\(b\)互质。
首先,我们需要考虑一个分数要成为纯循环小数需要满足什么条件。
我们先来回想一下,我们是怎样使用除法来判断一个分数$\frac{x}{y}$是否是纯循环小数的。显然我们是一路除下去,什么时候出现了相同的余数,那么这个数就是一个循环小数。如果第一个重复的余数是$x$,那么这个数就是纯循环小数。这种方法实际上就是存在一个数$l\neq 0$,使得:$$xk^l \equiv x (\bmod y)$$
又由于题目要求值不重复,那么我们可以得到$x \perp y$。所以,我们可以推出$k^l \equiv 1(\bmod y)$。所以我们只需$k \perp y$即可。
于是,我们实际上是要求这个式子:
\begin{aligned}&\sum_{x=1}^{n} \sum_{y=1}^{m}[x\perp y][y \perp k]\\=&\sum_{y=1}^{m}[y\perp k]\sum_{x=1}^{n}[x\perp y]\end{aligned}
用一下莫比乌斯反演,可以得到:
\begin{aligned}&\sum_{y=1}^{m}[y\perp k] \sum_{x=1}^{n}\sum_{d|x,d|y}\mu(d)\\=&\sum_{y=1}^{m}[y\perp k]\sum_{d|y}^{n}\mu(d)\lfloor \frac{n}{d}\rfloor \end{aligned}
再通过换一下枚举顺序,可得:
\begin{aligned}&\sum_{d=1}^{n}\mu(d)\lfloor \frac{n}{d} \rfloor \sum_{y=1}^{m}[d\ |\ y][y\perp k]\\=&\sum_{d=1}^{n}\mu(d)\lfloor \frac{n}{d}\rfloor \sum_{i=1}^{\lfloor \frac{m}{d} \rfloor}[id\perp k]\\=& \sum_{d=1}^{n}[d\perp k]\mu(d)\lfloor \frac{n}{d}\rfloor \sum_{i=1}^{\lfloor \frac{m}{d} \rfloor}[i\perp k]\end{aligned}
最后一步用了互质的一个性质,那就是$[ab\perp c]=[a\perp c][b\perp c]$。这点应该很好理解吧。
我们不妨设$f(n,k)=\sum_{i=1}^n[i\perp k]$,那么我们只要在$O(1)$的时间内求出$f$,复杂度就是$O(n)$,就可以得到$84$分。实际上,我们可以得到一个式子:
$$f(n,k)=\lfloor \frac{n}{k} \rfloor f(k,k)+f(n\bmod k,k)$$
这个应该也不难理解,因为$[a\perp b]=[a\bmod b \perp b]$
于是我们就可以对$f(n,k)$预处理出$n\le k$的值,每次求值就变成$O(1)$了。于是$84$分到手了。
我们考虑接下来该如何优化。由于$\lfloor \frac{m}{x} \rfloor$只有$\sqrt{m}$种取值,$\lfloor \frac{n}{x} \rfloor$只有$\sqrt{n}$种取值,于是我们显然可以分段求和。然后,我们就需要快速求出$\sum_{i=1}^n[i\perp k]\mu(i)$的值。
不妨设$g(n,k)=\sum_{i=1}^n[i\perp k]\mu(i)$,我们来考虑一下这个函数如何快速求。我们先考虑$k$的一个质因数$p$,那么$k$显然可以写成$p^cq$的形式。由于在$[1,n]$的范围中只有与$k$互质的才是有效值,那么若$x\perp k$,我们可以得到$x\perp p$并且$x\perp q$。于是,我们可以考虑从$x\perp q$的取值中减去$x$不与$p$互质的部分,就可以得到$x\perp k$的部分。这里如果不懂的话可以自己画一个$x\perp q$,$x\perp p$,$x\perp k$的关系图理解一下。
由于所有与$q$互质的数一定可以写成$p^xy(y\perp q)$的形式。那么我们需要减去的数一定满足$x>0$。又由于当$x>1$时$\mu(p^xy)=0$,所以我们只需要考虑$x=1$的情况即可。在这种情况下,我们需要考虑的数就是$py(y\perp q)$的形式,所以我们可以得到如下式子:\begin{aligned} g(n,k)&=\sum_{i=1}^n[i\perp q]\mu(i)-\sum_{y=1}^{\lfloor\frac{n}{p}\rfloor}[py\perp q]\mu(py) \\&=g(n,q)- \sum_{y=1}^{\lfloor\frac{n}{p}\rfloor}[y\perp q]\mu(py)\end{aligned}
上面的最后一步是由于$p\perp q$,所以$py\perp q$只需在保证$y\perp q$即可。
我们接着来考虑后一个式子。显然当$p\perp y$的时候$\mu(py)=\mu(p)\mu(y)$,否则$\mu(py)=0$。于是,我们又得到了:
\begin{aligned} g(n,k)&=g(n,q)- \sum_{y=1}^{\lfloor\frac{n}{p}\rfloor}[y\perp p][y\perp q]\mu(p)\mu(y)\\&=g(n,q)-\mu(p)\sum_{y=1}^{\lfloor\frac{n}{p}\rfloor}[y\perp k]\mu(y)\\&=g(n,q)+g(\lfloor\frac{n}{p}\rfloor,k) \end{aligned}
于是我们就可以递归求解了。容易发现边界情况就是$n=0$或者$k=1$。$n=0$的时候直接返回$0$就可以了,$k=1$的时候就是莫比乌斯函数的前缀和,用杜教筛求出来就可以了。由于每次递归要么$n$会变成$\lfloor \frac{n}{p} \rfloor$,有$O(\sqrt{n})$种取值;要么$p$少了一个质因数,有$\omega(k)$种取值,所以总共有$O(\omega(k)\sqrt{n})$种取值,记忆化搜索即可。其中$\omega(k)$表示$k$的不同的质因子数目。于是最后的总复杂度为$O(\omega(k)\sqrt{n}+n^{\frac{2}{3}})$,可以通过此题。
两个细节:
可以在递归求$g$的时候不直接记$k$,而是记录$k$还剩下多少个质因数,方便存储;
记忆化的时候可以开哈希链表存储,用$map$也可以,或者干脆分$n,m$以及小于、大于根号的情况存储也可以。
第一次写这种题的题解,好像写得过于详细了(其实是因为我什么都不会),请大神们不要喷……
下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 5000010
#define mod 100007
#define maxk 2010 using namespace std;
typedef long long llg; int n,m,k,pr_k[maxk],lp;
int s[maxn],ls,f[maxk];
int head[mod],next[maxn],to[maxn],tt;
int h1[11][mod],n1[maxn],t1[maxn],t2;
bool vis[maxn],huzhi[maxk];
llg ans,zto[maxn],zt1[maxn],mu[maxn]; int gcd(int a,int b){
int r=a%b;
while(r) a=b,b=r,r=a%b;
return b;
} void pre(){
mu[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]) s[++ls]=i,mu[i]=-1;
for(int j=1;j<=ls && s[j]*i<maxn;j++){
vis[s[j]*i]=1;
if(i%s[j]) mu[i*s[j]]=-mu[i];
else{mu[i*s[j]]=0;break;}
}
}
for(int i=2;i<maxn;i++) mu[i]+=mu[i-1];
for(int i=1;i<=k;i++){
huzhi[i]=(gcd(i,k)==1);
f[i]=f[i-1]+huzhi[i];
}
} llg suan(int x){return (x/k)*f[k]+f[x%k];}
llg solveu(int x){
if(x<maxn) return mu[x];
for(int i=head[x%mod];i;i=next[i]) if(to[i]==x) return zto[i];
int now=++tt; to[tt]=x;next[tt]=head[x%mod];head[x%mod]=tt; zto[now]=1;
for(int i=2,nt=0;nt<x;i=nt+1) nt=x/(x/i),zto[now]-=(nt-i+1)*solveu(x/i);
return zto[now];
} llg g(int x,int y){
if(!x) return solveu(y);
if(y<=1) return y;
for(int i=h1[x][y%mod];i;i=n1[i]) if(t1[i]==y) return zt1[i];
int now=++t2; t1[t2]=y;n1[t2]=h1[x][y%mod];h1[x][y%mod]=t2;
return zt1[now]=g(x-1,y)+g(x,y/pr_k[x]);
} int main(){
File("a");
scanf("%d %d %d",&n,&m,&k);
pre();
for(int i=1;s[i]<=k;i++) if(k%s[i]==0) pr_k[++lp]=s[i];
for(int d=1,l=min(n,m),nt;d<=l;d=nt+1){
nt=min(n/(n/d),m/(m/d));
ans+=(g(lp,nt)-g(lp,d-1))*(llg)(n/d)*suan(m/d);
}
printf("%lld",ans);
return 0;
}
最后附一个BZOJ的提交网址:BZOJ 4652 循环之美
UOJ #221 【NOI2016】 循环之美的更多相关文章
- [UOJ#221][BZOJ4652][Noi2016]循环之美
[UOJ#221][BZOJ4652][Noi2016]循环之美 试题描述 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在 k 进制下,一个数的小数部 ...
- luogu 1587 [NOI2016]循环之美
LINK:NOI2016循环之美 这道题是 给出n m k 求出\(1\leq i\leq n,1\leq j\leq m\) \(\frac{i}{j}\)在k进制下是一个纯循环的. 由于数值相同的 ...
- bzoj4652 [Noi2016]循环之美
Description 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在k进制下,一个数的小数部分是纯循环的,那么它就是美的.现在,牛牛想知道:对于已知 ...
- [NOI2016]循环之美
Description 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在 k 进制下,一个数的小数部分是纯循环的,那么它就是美的.现在,牛牛想知道:对 ...
- BZOJ4652: [Noi2016]循环之美(莫比乌斯反演,杜教筛)
Description 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在 k 进制下,一个数的小数部分是纯循环的,那么它就是美的.现在,牛牛想知道:对 ...
- BZOJ4652 [Noi2016]循环之美 【数论 + 莫比乌斯反演 + 杜教筛】
题目链接 BZOJ 题解 orz 此题太优美了 我们令\(\frac{x}{y}\)为最简分数,则\(x \perp y\)即,\(gcd(x,y) = 1\) 先不管\(k\)进制,我们知道\(10 ...
- luogu P1587 [NOI2016]循环之美
传送门 首先要知道什么样的数才是"纯循环数".打表可以发现,这样的数当且仅当分母和\(k\)互质,这是因为,首先考虑除法过程,每次先给当前余数\(*k\),然后对分母做带余除法,那 ...
- 题解 P1587 【[NOI2016]循环之美】
知识点:莫比乌斯反演 积性函数 杜教筛 废话前言: 我是古明地恋,写这篇题解的人已经被我 请各位读者自行无视搞事的恋恋带有删除线的内容,谢谢茄子. 这道题目本身并不难,但是公式推导/代码过程中具有迷惑 ...
- BZOJ4652 NOI2016循环之美(莫比乌斯反演+杜教筛)
因为要求数值不同,不妨设gcd(x,y)=1.由提示可以知道,x/y是纯循环小数的充要条件是x·klen=x(mod y).因为x和y互质,两边同除x,得klen=1(mod y).那么当且仅当k和y ...
- [NOI2016]循环之美(杜教筛)
首先要求每个数互不相等,故有$x\perp y$. 可以发现$\frac{x}{y}$在$k$进制下为纯循环小数的充要条件为$x\cdot k^{len}\equiv x(mod\ y)$,即$y\p ...
随机推荐
- linux内核调试技术之printk
原创博客:欢迎转载,转载请注明出处https://i.cnblogs.com/EditPosts.aspx?postid=6218383 1.简介(基于s3c2440 linux) 在内核调试技术之中 ...
- 1000行代码实现MVVM (类似Angular1.x.x , Vue)
最近花了近半个多月的时间, 自己纯手工写了一个很小型的类angularjs/vue的mvvm 库. 目前已经用于公司一个项目. 项目托管在github https://github.com/leonw ...
- TypeScript 强类型 JavaScript – Rafy Web 框架选型
今天看到了 AngularJs 2.0 版本将基于 TypeScript 构建 的消息.与同事们对 TypeScript 展开了讨论.本文记录一些个人的想法. 理想的 JavaScript 开发模式 ...
- Scala快速概览
IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...
- 几道web前端练习题目
在 HTML 语言中,以下哪个属性不是通用属性?A]<class>B]<title>C]<href>D]<style> 在线练习:http://hove ...
- Asp.Net MVC 从数据库生成代码(包括页面)
项目需要,数据库已经设计完成,需要生成相关的数据访问代码和页面. 参考:http://www.tracefact.net/asp-net/aspnetmvc-model-part1.aspx http ...
- 初识Git
Git是目前世界上最先进的分布式版本控制系统.在Git诞生之前,我们一直使用的是集中式版本控制系统(如CVS.SVN等),那么两者有什么不同呢?分布式的优势又在哪里呢? 分布式vs集中式 集中式版本控 ...
- 这个图片切换动画只用CSS3实现
体验效果:http://hovertree.com/texiao/css3/39/ 这是一个使用纯CSS3实现的图文切换效果,没使用js脚本.点击左右箭头或者索圆点引按钮可以切换内容. 本特效中使用到 ...
- 大朋展翅 html5上传图片(三)一解决部分手机拍相册批量上传图片转向问题
在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题.既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决.修改一下需要旋转图 ...
- Bootstrap之导航条
基本导航条 <!-- navbar-inverse相反颜色风格 --> <!-- navbar-static-top去除圆角 --> <!-- navbar-fixed- ...