Description

给一个长度为 \(n\) 的数组 \(a[1\dots n]\) ,满足 \(\sum_{m|x}a[x] = \mu(m)\),求 \(a[m]\)。

\(n\le 10^{18}, m\le 10^9, \frac{n}{m}\le10^9,n\geq m\)

Solution

由另一种形式的莫比乌斯反演:

\[\begin{aligned}
a[m] &= \sum_{m|x}\mu(\frac{x}{m})\mu(x)\\
&=\sum_{i=1}^{\frac{n}{m}}\mu(i)\mu(im)\\
&=\mu(m)\sum_{i=1}^{\lfloor\frac{n}{m}\rfloor}\mu(i)^2[\gcd(i, m) = 1]\\
\end{aligned}
\]

后面那个 \(\sum\) 就是在求 \(1\dots \frac{n}{m}\) 中与 \(m\) 互质且不能写成完全平方数的倍数的个数。

类似于 [中山市选2011]完全平方数,可以容斥求:

令 \(N = \lfloor\frac{n}{m}\rfloor\),

\[\begin{aligned}
a[m] &=\mu(m)\sum_{i=1}^{\frac{n}{m}}\mu(i)^2[\gcd(i, m) = 1]\\
&=\mu(m)\sum_{i=1}^{\sqrt{N}}\mu(i)\sum_{j=1}^{\lfloor\frac{N}{i^2}\rfloor}[\gcd(i^2j,m)=1]\\
&=\mu(m)\sum_{i=1}^{\sqrt{N}}\mu(i)[\gcd(i,m)=1]\sum_{j=1}^{\lfloor\frac{N}{i^2}\rfloor}[\gcd(j,m)=1]\\
&=\mu(m)\sum_{i=1}^{\sqrt{N}}\mu(i)[\gcd(i,m)=1]\sum_{j=1}^{\lfloor\frac{N}{i^2}\rfloor}\sum_{d|\gcd(j,m)}\mu(d)\\
&=\mu(m)\sum_{i=1}^{\sqrt{N}}\mu(i)[\gcd(i,m)=1]\sum_{d|m}\mu(d)\lfloor\frac{\lfloor\frac{N}{i^2}\rfloor}{d}\rfloor
\end{aligned}
\]

然后就可以把 \(m\) 的所有约数处理出来,暴力算(复杂度上界为 \(O(T\sqrt \frac{n}{m} \sqrt m)\),实际后面的 \(\sqrt m\) 跑不满)。

注意\(\mu\)要筛到\(\sqrt N\)复杂度才是对的(不然多一个根号)。

code

#include <bits/stdc++.h>

typedef long long LL;
typedef unsigned long long uLL; #define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define MP(x, y) std::make_pair(x, y)
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define GO cerr << "GO" << endl; using namespace std; inline void proc_status()
{
ifstream t("/proc/self/status");
cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
} template<class T> inline T read()
{
register T x(0);
register char c;
register int f(1);
while (!isdigit(c = getchar())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
return x * f;
} template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; } const int maxN = 1e5; bool vis[maxN + 1];
vector<int> prime;
int mu[maxN + 1];
LL n, m; void Init()
{
mu[1] = 1;
for (int i = 2; i <= maxN; ++i)
{
if (!vis[i])
{
prime.push_back(i);
mu[i] = -1;
}
for (int j = 0; j < SZ(prime) and prime[j] * i <= maxN; ++j)
{
vis[prime[j] * i] = 1;
if (i % prime[j] == 0)
break;
else
mu[i * prime[j]] = -mu[i];
}
}
} int Mu(LL M)
{
if (M <= maxN) return mu[M];
//GO;
int cnt = 0;
for (LL i = 2; i * i <= M; ++i)
if (M % i == 0)
{
M /= i;
cnt++;
if (M % i == 0)
return 0;
}
if (M != 1) cnt++;
return (cnt & 1) ? -1 : 1;
} vector<pair<LL, int> > p; LL calc(LL i)
{
LL ans(0);
for (int l = 0; l < SZ(p); ++l)
ans += (LL)p[l].second * (((n / m) / (i * i)) / p[l].first);
return ans;
} void GetP(LL m)
{
p.clear();
for (LL d = 1; d * d <= m; ++d)
if (m % d == 0)
{
p.push_back(MP(d, Mu(d)));
if (m / d == d) continue;
p.push_back(MP(m / d, Mu(m / d)));
}
} void Solve()
{
int T = read<int>();
while (T--)
{
n = read<LL>(), m = read<LL>(); GetP(m); LL ans(0);
for (LL i = 1; i * i <= (n / m); ++i)
if (__gcd((LL)i, m) == 1)
ans += Mu(i) * calc(i);
ans *= Mu(m); printf("%lld\n", ans);
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("xhc.in", "r", stdin);
freopen("xhc.out", "w", stdout);
#endif
Init();
Solve();
return 0;
}

[P5348]密码解锁的更多相关文章

  1. 【洛谷】P5348 密码解锁

    [洛谷]P5348 密码解锁 很显然我们可以推导出这个式子 设\(a(m)\)为\(m\)位置的值 \[ \mu(m) = \sum_{m | d} a(d) \\ a(m) = \sum_{m|d} ...

  2. Swift 简简单单实现手机九宫格手势密码解锁

    原文:Swift 简简单单实现手机九宫格手势密码解锁 大家可以看到我之前的文章[HTML5 Canvas简简单单实现手机九宫格手势密码解锁] 本文是使用苹果语言对其进行了移植 颜色配色是拾取的支付宝的 ...

  3. HTML5 Canvas简简单单实现手机九宫格手势密码解锁

    原文:HTML5 Canvas简简单单实现手机九宫格手势密码解锁 早上花了一个半小时写了一个基于HTML Canvas的手势解锁,主要是为了好玩,可能以后会用到. 思路:根据配置计算出九个点的位置,存 ...

  4. 【Luogu5348】密码解锁(莫比乌斯反演,数论)

    [Luogu5348]密码解锁(莫比乌斯反演,数论) 题面 洛谷 题解 首先题目给定的限制是\(\sum_{n|i}a[i]=\mu(n)\),然后把这个东西反演一下, 莫比乌斯反演的式子是:\(g( ...

  5. Oracle 修改密码 解锁

    1.怎么修改oracle用户密码 在以SYSDBA身份登陆时可以修改其他用户的密码,比如: SQL> alter user 用户名 identified by 新密码; 用户已更改. 这个是把U ...

  6. Luogu5348 密码解锁

    题面 题解 记\(N = \dfrac nm\) 这道题目就是要求\(a_m = \sum_{i=1}^N \mu(i)\mu(im)\) 因为\(\mu(ij) = \mu(i)\mu(j)[\gc ...

  7. iOS 10的正确解锁方式

    在iOS 10上,锁屏状态通过按下电源键点亮屏幕之后,用手指轻触Home键,实际上手机是已经解锁了的,不信请看如下截图: 虽然手机已经解锁,但与iOS 9不同的是,此时手机还处在解锁界面而没有进入主屏 ...

  8. android 判断是否设置了锁屏密码

    方式1:在小米note手机上测试,只能判断是否设置了图形解锁. android.provider.Settings.System.getInt(getContentResolver(), androi ...

  9. Appnium+python实现手势密码为什么总是报错

    最近一直在尝试Appnium实现Android手机自动化测试,一直一直卡在一个点上,那就是手势密码,因为所测应用的手势密码使用的不是单个的imageview实现的手势密码解锁窗,所以只能靠坐标点来定位 ...

随机推荐

  1. PHP入门(四)

    1.数组 1. array() 函数用于创建数组 在 PHP 中,有三种类型的数组:数值数组 - 带有数字 ID 键的数组 关联数组 - 带有指定的键的数组,每个键关联一个值 多维数组 - 包含一个或 ...

  2. JS几种数组遍历方式总结

    JS数组遍历的几种方式 JS数组遍历,基本就是for,forin,foreach,forof,map等等一些方法,以下介绍几种本文分析用到的数组遍历方式以及进行性能分析对比 第一种:普通for循环 代 ...

  3. artTemplate字符串模板

    1.官网:http://aui.github.io/art-template/

  4. UML——用例视图

    用例视图中交互功能部分被称为用例.   参与者   作为外部用户与系统发生交互作用,这是参与者的特征. 在系统的实际运作中,一个实际用户可能对应系统的多个参与者.不同的用户也可以只对应于一个参与者,从 ...

  5. 【深入理解CLR】1:CLR的执行模型

    将源代码编译成托管模块 下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模 ...

  6. TTTTTTTTTTTTTTTTT HDU 2586 How far away LCA的离线算法 Tarjan

    链接: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  7. SQL模糊查询报:ORA-00909:参数个数无效

    用oracle数据库进行模糊查询时,控制台报错如下图所示: 原因是因为敲的太快,语法写错了 正确的写法是 pd.code like concat(concat('%',#{keyword}),'%')

  8. idea中查看一个类的调用用和被调用用关系

  9. Centos 建一个指定大小的文件夹

    1.使用ramdisklinux可以把一部分内存mount为分区使用,通常为称为ramdisk,分为ramdisk, ramfs, tmpfs.可以一条命令实现我们的需求:mount none tes ...

  10. Unsupervised Image-to-Image Translation Networks

    Abstract: 无监督图像到图像的翻译目的是学习不同域图像的一个联合分布,通过使用来自单独域图像的边缘分布.给定一个边缘分布,可以得到很多种联合分布.如果不加入额外的假设条件的话,从边缘分布无法推 ...