博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI2016]循环之美
阅读量:5794 次
发布时间:2019-06-18

本文共 2862 字,大约阅读时间需要 9 分钟。

题如其名,这道题十分优美

首先,如果$\dfrac xy$在$k$进制下是循环节长度为$l$的纯循环小数,那么$\dfrac xy$和$\dfrac{xk^l}y$的小数部分是一样的,也就是说$x\equiv xk^l(\bmod y)$,即$k^l\equiv1(\bmod y)$,这时就有$(k,y)=1$,显然以上每一步都是充分必要的

所以我们要求$\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(i,j)=1][(j,k)=1]$,先推一下式子

$\begin{aligned}\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(i,j)=1][(j,k)=1]&=\sum\limits_{j=1}^m[(j,k)=1]\sum\limits_{i=1}^n\sum\limits_{\substack{d|i\\d|j}}\mu(d)\\&=\sum\limits_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\frac nd\right\rfloor\sum\limits_{j=1}^{\left\lfloor\frac md\right\rfloor}[(jd,k)=1]\\&=\sum\limits_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\frac nd\right\rfloor[(d,k)=1]\sum\limits_{j=1}^{\left\lfloor\frac md\right\rfloor}[(j,k)=1]\end{aligned}$

现在我们要求两个东西:$f(n)=\sum\limits_{i=1}^n[(i,k)=1]$和$g(n,k)=\sum\limits_{i=1}^n\mu(i)[(i,k)=1]$

$f(n)=\left\lfloor\frac nk\right\rfloor f(k)+f(n\%k)$,预处理$f(1\cdots k)$即可

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

中间多出来的中括号不是无中生有,因为如果$(i,d)\ne1$那么$\mu(id)=0$,这一步是比较妙的地方

于是我们可以递归求值,递归到$k=1$时直接杜教筛,这里的时间复杂度是$O(n^{\frac23})$,观察递归式,我们可以只分析$d$的取值,有$O(\sigma_0(k))$个不同的$d$,每次转移耗费时间为$O(\sigma_0(d))$,加上最外层的根号分段,总时间复杂度为$O\left(n^{\frac23}+\sigma_0^2(k)\sqrt n\right)$,当然这个上界很松,所以跑得还是挺快的

The beautiful math.

#include
#include
#include
using namespace std;typedef long long ll;const int T=1000000;int pr[T+10],mu[T+10],smu[T+10];bool np[T+10];void sieve(){ int i,j,M=0; mu[1]=1; for(i=2;i<=T;i++){ if(!np[i]){ pr[++M]=i; mu[i]=-1; } for(j=1;j<=M&&i*pr[j]<=T;j++){ np[i*pr[j]]=1; if(i%pr[j]==0)break; mu[i*pr[j]]=-mu[i]; } } for(i=1;i<=T;i++)smu[i]=smu[i-1]+mu[i];}int gcd(int a,int b){return a%b==0?b:gcd(b,a%b);}int f[2010];map
g[2010];int get(int n,int k){ if(n==0)return 0; if(g[k].count(n))return g[k][n]; if(k==1){ if(n<=T)return smu[n]; if(g[1].count(n))return g[1][n]; int i,nex,s; s=1; for(i=2;i<=n;i=nex+1){ nex=n/(n/i); s-=(nex-i+1)*get(n/i,1); } return g[1][n]=s; } int i,s; s=0; for(i=1;i*i<=k;i++){ if(k%i==0){ if(mu[i])s+=get(n/i,i); if(i*i!=k&&mu[k/i])s+=get(n/(k/i),k/i); } } return g[k][n]=s;}int main(){ sieve(); int n,m,k,i,N,nex; ll s; scanf("%d%d%d",&n,&m,&k); for(i=1;i<=k;i++)f[i]=f[i-1]+(gcd(i,k)==1); N=min(n,m); s=0; for(i=1;i<=N;i=nex+1){ nex=min(n/(n/i),m/(m/i)); s+=(n/i)*((m/i/k)*(ll)f[k]+f[m/i%k])*(get(nex,k)-get(i-1,k)); } printf("%lld",s);}

转载于:https://www.cnblogs.com/jefflyy/p/9503906.html

你可能感兴趣的文章
java中ArrayList 、LinkList区别
查看>>
Spring ’14 Wave Update: Installing Dynamics CRM on Tablets for Windows 8.1
查看>>
利用rand7()构造rand10()
查看>>
MySQL 备份与恢复
查看>>
吃午饭前,按书上的代码写会儿--Hunt the Wumpus第一个版本
查看>>
easyui中combobox的值改变onchang事件
查看>>
TEST
查看>>
PAT A1037
查看>>
ReactiveSwift源码解析(三) Signal代码的基本实现
查看>>
(六)Oracle学习笔记—— 约束
查看>>
[Oracle]如何在Oracle中设置Event
查看>>
top.location.href和localtion.href有什么不同
查看>>
02-创建hibernate工程
查看>>
Open Graph Protocol(开放内容协议)
查看>>
Ubuntu18.04中配置QT5.11开发环境
查看>>
Exception的妙用
查看>>
知识图谱在互联网金融中的应用
查看>>
MySQL 到底能不能放到 Docker 里跑?
查看>>
【docker】关于docker 中 镜像、容器的关系理解
查看>>
information_schema系列五(表,触发器,视图,存储过程和函数)
查看>>