题解

我们要求的其实是这个东西= =

\(\sum_{i = 1}^{n}\sum_{j = 1}^{n}[(i,j) == 1][(j,k) == 1]\)

然后变一下形

\(\sum_{j = 1}^{n}[(j,k) == 1]\sum_{i = 1}^{n}[(i,j) == 1]\)

\(\sum_{j = 1}^{n}[(j,k) == 1]\sum_{i = 1}^{n}\sum_{d|i,j}\mu(d)\)

\(\sum_{j = 1}^{n}[(j,k) == 1]\sum_{d | j} \mu(d) \lfloor \frac{n}{d} \rfloor\)

\(\sum_{d = 1}^{n} \mu(d) \lfloor \frac{n}{d} \rfloor \sum_{y = 1}^{\lfloor \frac{m}{d} \rfloor}[(yd,k) == 1]\)

\(\sum_{d = 1}^{n} \mu(d) \lfloor \frac{n}{d} \rfloor \sum_{y = 1}^{\lfloor \frac{m}{d} \rfloor}[(d,k) == 1][(y,k) == 1]\)

\(\sum_{d = 1}^{n} [(d,k) == 1] \mu(d) \lfloor \frac{n}{d} \rfloor \sum_{y = 1}^{\lfloor \frac{m}{d} \rfloor}[(y,k) == 1]\)

设\(f(n) = \sum_{i = 1}^{n}[(i,k) == 1]\)

我们可以预处理\(f(1)\)到\(f(k)\)

那么就有

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

因为\((a,b) == 1\) 等价于\((a mod b,b) == 1\)

我们现在可以\(O(n)\)解决这个式子了,但是还不够

我们可以用数论分块处理\(\lfloor \frac{n}{d} \rfloor\) 和 \(\lfloor \frac{m}{d} \rfloor\)

我们尝试算

\(\sum_{d = 1}^{n} [(d,k) == 1] \mu(d)\)

设\(g(n,k) = \sum_{d = 1}^{n} [(d,k) == 1] \mu(d)\)

我们选择一个\(k\)的质因子\(p\),然后把\(k\)表示成\(p^{c}q\)的形式

我们从和\(q\)互质的数里除掉和\(p\)互质的数

\(g(n,k) = \sum_{d = 1}^{n} [(d,q) == 1] \mu(d) - \sum_{y = 1}^{n} [(yp,q) == 1] \mu(yp)\)

由于\(p\)和\(q\)互质,所以我们只需要保证\([(y,p) == 1][(y,q) == 1]\)

\(g(n,k) = \sum_{d = 1}^{n} [(d,q) == 1] \mu(d) - \mu(p) \sum_{y = 1}^{n} [(y,p) == 1][(y,q) == 1] \mu(y)\)

\(g(n,k) = \sum_{d = 1}^{n} [(d,q) == 1] \mu(d) + \sum_{y = 1}^{\lfloor \frac{n}{d} \rfloor} [(y,k) == 1]\mu(y)\)

\(g(n,k) = g(n,q) + g(\lfloor \frac{n}{p} \rfloor,k)\)

边界是\(n <= 1\)返回\(n\),\(k = 1\)返回一个莫比乌斯函数的前缀和,可以杜教筛

代码

#include <bits/stdc++.h>
//#define ivorysi
#define enter putchar('\n')
#define space putchar(' ')
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eps 1e-8
#define mo 974711
#define MAXN 1000000
#define pii pair<int,int>
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,M,K;
int mu[MAXN + 5],prime[MAXN + 5],tot,Mu[MAXN + 5];
bool nonprime[MAXN + 5];
int f[2005];
struct HASH {
struct node {
int64 x,v;
int next;
}E[MAXN * 2];
int head[mo + 5],sumE;
HASH() {
memset(head,0,sizeof(head));sumE = 0;
}
void add(int u,int64 x,int64 v) {
E[++sumE].x = x;E[sumE].v = v;E[sumE].next = head[u];
head[u] = sumE;
}
void Insert(int64 x,int64 v) {
add(x % mo,x,v);
}
int64 Query(int64 x){
for(int i = head[x % mo] ; i ; i = E[i].next) {
if(E[i].x == x) return E[i].v;
}
return -1;
}
}H[2];
int gcd(int a,int b) {
return b == 0 ? a : gcd(b,a % b);
}
int64 calcF(int x) {
return 1LL * (x / K) * f[K] + f[x % K];
}
int64 S(int x) {
if(x <= MAXN) return Mu[x];
int64 c = H[0].Query(x);
if(c != -1) return c;
int64 res = 0;
for(int i = 2 ; i <= x ; ++i) {
int r = x / (x / i);
res = res + 1LL * (r - i + 1) * S(x / i);
i = r;
}
res = 1 - res;
H[0].Insert(x,res);
return res;
}
int64 G(int n,int k) {
if(k == 1) return S(n);
else if(n <= 1) return n;
int64 c = H[1].Query(1LL * (n - 1) * K + k);
if(c != -1) return c;
for(int i = 1 ; i <= tot ; ++i) {
if(k % prime[i] == 0) {
int x = k;
while(x % prime[i] == 0) x /= prime[i];
int64 res = G(n,x) + G(n / prime[i],x * prime[i]);
H[1].Insert(1LL * (n - 1) * K + k,res);
return res;
}
} }
void Solve() {
int t = min(N,M);
int64 res = 0;
for(int i = 1 ; i <= t ; ++i) {
int r = min(N / (N / i),M / (M / i));
int64 s = calcF(M / i) * (N / i);
res = res + s * (G(r,K) - G(i - 1,K));
i = r;
}
out(res);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);read(M);read(K);
mu[1] = 1;Mu[1] = 1;
for(int i = 2 ; i <= MAXN ; ++i) {
if(!nonprime[i]) {
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1 ; j <= tot ; ++j) {
if(prime[j] > MAXN / i) break;
nonprime[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
else mu[i * prime[j]] = -mu[i];
}
Mu[i] = Mu[i - 1] + mu[i];
}
for(int i = 1 ; i <= K ; ++i) {
f[i] = f[i - 1] + (gcd(i,K) == 1);
}
Solve();
return 0;
}

【LOJ】#2085. 「NOI2016」循环之美的更多相关文章

  1. *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 ...

  2. LibreOJ2085 - 「NOI2016」循环之美

    Portal Description 给出\(n,m(n,m\leq10^9)\)和\(k(k\leq2000)\),求在\(k\)进制下,有多少个数值不同的纯循环小数可以表示成\(\dfrac{x} ...

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

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

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

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

  5. 「NOI2016」循环之美

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

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

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

  7. 【刷题】LOJ 2818 「eJOI2018」循环排序

    题目描述 本题译自 eJOI2018 Problem F「Cycle Sort」 给定一个长为 \(n\) 的数列 \(\{a_i\}\) ,你可以多次进行如下操作: 选定 \(k\) 个不同的下标 ...

  8. LOJ#2086. 「NOI2016」区间

    $n \leq 500000$个区间,从中挑出一些,使得至少有一个点被$m$个选中区间包含,且选中区间长度的极差最小. 区间题死脑筋晚期:把区间按左端点排序,然后右端点用个优先队列来弹,然后需要维护下 ...

  9. LOJ#2084. 「NOI2016」网格

    $n,m \leq 1e9$,$n*m$的网格中有$c \leq 1e5$个是黑的,其他是白的.问:使至少两个白的不连通,最少需要再把几个白的涂黑. 可以发现答案是-1,0,1,2啦.-1要么没白的, ...

随机推荐

  1. Codeforces Round #305 (Div. 2) D 维护单调栈

    D. Mike and Feet time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  2. python---websocket的使用

    一:简介 推文:WebSocket 是什么原理?为什么可以实现持久连接? 推文:WebSocket:5分钟从入门到精通(很好) WebSocket协议是基于TCP的一种新的协议.WebSocket最初 ...

  3. web启动@Autowired不能自动注入

    使用struts2,下面为action代码 Java代码 package com.edar.web.platform; import org.apache.struts2.convention.ann ...

  4. 51nod 1449 砝码称重 (进制思想)

    1449 砝码称重 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 现在有好多种砝码,他们的重量是 w0,w1,w ...

  5. Python学习笔记(三十三)常用内置模块(2)collections_namedtuple_deque_defaultdict_OrderedDict_Counter

    摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431953239 ...

  6. Python学习笔记(三十二)常用内建模块(1)— datetime

    >>> from datetime import datetime >>> now = datetime.now() # 获取当前datetime >> ...

  7. 如何修改 winserver2008 密码策略为简单密码

    对于不在域中的计算机, 可以运行: gpedit.msc , 如下图: 对于在域中的计算机, 应该: 如不能生效, 可重启再试.

  8. 更改gradle的java的class文件输出目录的结构

    group 'com.thinkvenus.common'version '1.0-SNAPSHOT' apply plugin: 'java' sourceCompatibility = 1.8 r ...

  9. MySql 快速去重方法

    1.复制需要去重的表 CREATE TABLE 新表 LIKE 旧表 ; 2.将需要去重的字段 设置为唯一union 索引 ALTER TABLE 表名 ADD UNIQUE(`字段`); 3.复制旧 ...

  10. python模块之imghdr检测图片类型

    1. imghdr是什么 imghdr是一个用来检测图片类型的模块,传递给它的可以是一个文件对象,也可以是一个字节流. 能够支持的图片格式: 2. 如何使用 提供了一个api叫做imghdr.what ...