当前位置: 首页 > news >正文

[NOI 2016]循环之美

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; }

转载于:https://www.cnblogs.com/NaVi-Awson/p/9259545.html

相关文章:

  • finereport连接oracle_FineReport连接多维数据库示例及操作
  • linux 扩展挂载盘大小_Linux下使用fdisk扩展分区容量
  • JavaScript (function (){}()) 与(function(){})()
  • python assert 不退出_Pytest中断言的重要性,就不需要我重复了吧
  • IDEA中Lombok插件的安装与使用
  • python坦克大战_python资料领取:尚学堂201903期python全栈(0基础到就业)
  • 【leetcode】88. 合并两个有序数
  • aix么把占用的端口释放掉_UNIX系统如何释放被异常占用的端口 - 河北分行(秦永峰)...
  • redis 多维度排序_解决Redis Cluster模式下的排序问题
  • python基础学习01
  • 不同平台安装python方式一样_大厦的基石,成为一个Python工程师的第一步——安装Python...
  • vue 多页面应用例子_用vue构建多页面应用
  • 6.7 二分查找
  • oracle手工收集awr报告_oracle手工生成AWR报告方法
  • 《杜拉拉升职记》//TODO
  • php的引用
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 2017届校招提前批面试回顾
  • 2017年终总结、随想
  • CentOS7简单部署NFS
  • HTML5新特性总结
  • idea + plantuml 画流程图
  • JavaScript标准库系列——Math对象和Date对象(二)
  • JAVA之继承和多态
  • node和express搭建代理服务器(源码)
  • python学习笔记-类对象的信息
  • Quartz初级教程
  • Vue.js 移动端适配之 vw 解决方案
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 马上搞懂 GeoJSON
  • 排序算法学习笔记
  • 如何在GitHub上创建个人博客
  • 使用Gradle第一次构建Java程序
  • 小程序 setData 学问多
  • 新书推荐|Windows黑客编程技术详解
  • 自定义函数
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • #### go map 底层结构 ####
  • #NOIP 2014# day.1 T2 联合权值
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • $.ajax()方法详解
  • (¥1011)-(一千零一拾一元整)输出
  • (1)Android开发优化---------UI优化
  • (1)STL算法之遍历容器
  • (10)STL算法之搜索(二) 二分查找
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (转) ns2/nam与nam实现相关的文件
  • (转)jQuery 基础
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • *上位机的定义
  • .Net Core 中间件验签
  • .Net 路由处理厉害了
  • .NET 事件模型教程(二)