51nod1965. 奇怪的式子(min_25筛)
题目链接
http://www.51nod.com/Challenge/Problem.html#!#problemId=1965
题解
需要求的式子显然是个二合一形式,我们将其拆开,分别计算 \(\prod_\limits{i = 1}^n \sigma_0(i)^i\) 与 \(\prod_\limits{i = 1}^n \sigma_0(i)^{\mu(i)}\),再将两部分乘起来得到答案。
对于第一部分 \(\prod_\limits{i = 1}^n \sigma_0(i)^i\):
由于若 \(x\) 的唯一分解式为 \(p_1^{\alpha_1}p_2^{\alpha_2} \cdots p_k^{\alpha_k}\),那么有 \(\sigma_0(x) = \prod_{i = 1}^k (\alpha_i + 1)\),因此我们可以考虑求每一个质数的贡献。令 \(P\) 表示质数集合,不难得到:
\]
其中的 \(w\) 即为所有唯一分解式中包含 \(p^k\) 的数的和,做个简单容斥可以得到 \(w = p^k \cdot s(\left\lfloor\frac{n}{p^k}\right\rfloor) - p^{k + 1} \cdot s(\left\lfloor\frac{n}{p^{k + 1}}\right\rfloor)\),\(s(x)\) 表示 \(1 \sim x\) 的所有数的和,即 \(\frac{x(x + 1)}{2}\)。
当 \(p \leq \sqrt n\) 时,我们可以直接暴力枚举 \(p\) 与 \(k\) 来计算式子的值。
当 \(p > \sqrt n\) 时,对应的 \(k\) 只可能为 \(1\),因此式子可以化为 \(2^{c}\) 的形式,其中 \(c = \sum_\limits{p \in P, p > \sqrt n} p \left\lfloor\frac{n}{p}\right\rfloor\)。考虑如何求 \(c\)。我们对 \(\left\lfloor\frac{n}{p}\right\rfloor\) 整除分块后,问题转化为了计算一段区间内所有质数的和,即求质数的前缀和。使用 min_25 筛即可。
对于第二部分 \(\prod_\limits{i = 1}^n \sigma_0(i)^{\mu(i)}\):
由于当 \(x\) 的唯一分解式中存在一个 \(p^{\alpha}\) 满足 \(\alpha > 1\) 时,\(\mu(x) = 0\),因此对答案式子 \(\prod_\limits{i = 1}^n \sigma_0(i)^{\mu(i)}\) 有贡献的 \(i\) 一定满足 \(i\) 是若干个互不相同的质数的乘积。显然,此时 \(\sigma_0(i)\) 又可以写成 \(2\) 的次幂的形式,且若 \(i\) 是 \(k\) 个互不相同的质数的乘积,那么 \(\sigma_0(i) = 2^k\)。因此若令 \(g(x)\) 表示 \(x\) 包含的不同的质因数的个数,那么有:
\]
其中 \(w = \sum_\limits{i = 1}^n \mu(i)g(i)\)。
令 \(P_i\) 表示从小到大第 \(i\) 个质数,\({\rm minp}(x)\) 表示 \(x\) 的最小质因子。使用 min_25 筛的思想,设 \(f_1(x, k) = \sum_\limits{i = 1}^x [i \in P\ 或\ {\rm minp}(i) > P_k]\mu(i)g(i)\),\(f_2(x, k) = \sum_\limits{i = 1}^x [i \in P\ 或\ {\rm minp}(i) > P_k]\mu(i)\),那么 \(w\) 即为 \(f_1(n, 0)\)。
我们按 \(k\) 从大到小求 \(f_1\) 与 \(f_2\)。考虑加上最小质因子为 \(P_k\) 的数的贡献,那么可以得到 \(f_2\) 的转移如下(注意随着质因子的增加,\(\mu\) 的符号会改变,因此新增的贡献前带有负号):
\]
同理可得 \(f_1\) 的转移如下:
\]
总时间复杂度即为 min_25 筛的时间复杂度,为 \(O(\frac{n^{\frac{3}{4}}}{\log n})\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
const long long mod = 1e12 + 39;
long long n, powk[N];
int tt, sq;
bool is_prime[N];
vector<int> primes;
vector<long long> values;
template<typename T>
struct my_array {
T a[N];
T& operator [] (long long x) {
return x <= sq ? a[x] : a[n / x + sq];
}
};
my_array<long long> g0, g1, f1, f2;
long long add(long long x, long long y, long long md) {
long long t = x + y;
if (t >= md) {
t -= md;
}
return t;
}
long long sub(long long x, long long y, long long md) {
long long t = x - y;
if (t < 0) {
t += md;
}
return t;
}
long long mul(long long x, long long y, long long md) {
long double t = (long double) x * y;
return (x * y - (long long) (t / md) * md) % md;
}
long long qpow(long long v, long long p) {
long long result = 1;
for (; p; p >>= 1, v = mul(v, v, mod)) {
if (p & 1) {
result = mul(result, v, mod);
}
}
return result;
}
void sieve(int n) {
memset(is_prime, true, sizeof is_prime);
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i);
}
for (auto v : primes) {
long long d = (long long) v * i;
if (d > n) {
break;
}
is_prime[d] = false;
if (i % v == 0) {
break;
}
}
}
}
long long same_diff(long long x) {
long long y = x + 1;
if (x & 1) {
y >>= 1;
} else {
x >>= 1;
}
return mul(x, y, mod - 1);
}
void min_25_sieve() {
for (long long i = 1; i <= n; i = n / (n / i) + 1) {
values.push_back(n / i);
}
for (auto x : values) {
g0[x] = x - 1;
g1[x] = sub(same_diff(x), 1, mod - 1);
}
for (auto p : primes) {
for (auto x : values) {
if (x < (long long) p * p) {
break;
}
long long y = x / p;
long long g0_t = g0[y] - g0[p - 1];
long long g1_t = sub(g1[y], g1[p - 1], mod - 1);
g0[x] -= g0_t;
g1[x] = sub(g1[x], mul(p, g1_t, mod - 1), mod - 1);
}
}
reverse(primes.begin(), primes.end());
for (auto x : values) {
f1[x] = f2[x] = sub(0, g0[x], mod - 1);
}
for (auto p : primes) {
for (auto x : values) {
if (x < (long long) p * p) {
break;
}
long long y = x / p;
long long f2_t = sub(f2[p], f2[y], mod - 1);
long long f1_t = sub(f1[p], f1[y], mod - 1);
f2[x] = add(f2[x], f2_t, mod - 1);
f1[x] = add(f1[x], add(f1_t, f2_t, mod - 1), mod - 1);
}
}
}
int main() {
scanf("%d", &tt);
while (tt--) {
scanf("%lld", &n);
sq = sqrt(n);
primes.clear();
values.clear();
memset(powk, 0, sizeof powk);
sieve(sq);
min_25_sieve();
long long answer = 1;
int maxk = 1;
for (auto p : primes) {
long long t = p;
for (int j = 1; t <= n; ++j, t *= p) {
long long num1 = mul(t, same_diff(n / t), mod - 1);
long long num2 = mul(t * p, same_diff(n / t / p), mod - 1);
maxk = max(maxk, j + 1);
powk[j + 1] = add(powk[j + 1], sub(num1, num2, mod - 1), mod - 1);
}
}
for (int i = 2; i <= maxk; ++i) {
answer = mul(answer, qpow(i, powk[i]), mod);
}
long long powm = 0;
for (long long i = sq + 1; i <= n; i = n / (n / i) + 1) {
long long j = n / (n / i);
powm = add(powm, mul(sub(g1[j], g1[i - 1], mod - 1), same_diff(n / i), mod - 1), mod - 1);
}
answer = mul(answer, qpow(2, powm), mod);
answer = mul(answer, qpow(2, f1[n]), mod);
printf("%lld\n", answer);
}
return 0;
}
51nod1965. 奇怪的式子(min_25筛)的更多相关文章
- 【51NOD1965】奇怪的式子 min_25筛
题目描述 给你\(n\),求 \[ \prod_{i=1}^n{\sigma_0(i)}^{i+\mu(i)} \] 对\({10}^{12}+39\)取模. \(\sigma_0(i)\)表示约数个 ...
- 51nod 1965 奇怪的式子——min_25筛
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 考虑 \( \prod_{i=1}^{n}\sigma_0^i \) \ ...
- 51nod 1965 奇怪的式子 —— min_25筛
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 推式子就同这里:https://www.cnblogs.com/yoyo ...
- 【51NOD1847】奇怪的数学题 min_25筛
题目描述 记\(sgcd(i,j)\)为\(i,j\)的次大公约数. 给你\(n\),求 \[ \sum_{i=1}^n\sum_{j=1}^n{sgcd(i,j)}^k \] 对\(2^{32}\) ...
- 51nod1847 奇怪的数学题 (Min_25筛+第二类斯特林数)
link \(\sum_{i=1}^n\sum_{j=1}^n\mathrm{sgcd}(i,j)^k=\sum_{p=1}^ns(p)^k\sum_{i=1}^n\sum_{j=1}^n[\gcd( ...
- [51nod1965]奇怪的式子
noteskey 怎么说,魔性的题目...拿来练手 min_25 正好...吧 首先就是把式子拆开来算贡献嘛 \[ANS=\prod_{i=1}^n \sigma_0(i)^{\mu(i)} \pro ...
- 【51nod1965】奇怪的式子
Portal --> 51nod1965 Solution 怎么说呢..这题..做的有点痛苦.. 首先看这个式子长得..比较奇怪,指数里面那个加号有点烦人,而且这个函数不是一个积性函数也有点烦人 ...
- 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数)
[51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...
- 【UOJ448】【集训队作业2018】人类的本质 min_25筛
题目大意 给你 \(n,m\),求 \[ \sum_{i=1}^n\sum_{x_1,x_2,\ldots,x_m=1}^i\operatorname{lcm}(\gcd(i,x_1),\gcd(i, ...
随机推荐
- Disruptor 系列(一)快速入门
Disruptor 系列(一)快速入门 Disruptor:是一个开源的并发框架,能够在 无锁 的情况下实现网络的 Queue 并发操作,所以处理数据的能力比 Java 本身提供的并发类容器要大的多, ...
- android安装前期遇到的问题
1.安装的eclipse与对应的java版本位数要一致,要么32位,要么64位. 2.关于新版ADT创建项目时出现appcompat_v7的问题 更新ADT至22.6.0版本之后,创建新的安装项目,会 ...
- CodeForces 681A A Good Contest (水题)
题意:给定 n 个人和before, after的分数,让你找 before 的分数大于等于2400并且before 小于 after. 析:看完题意就知道怎么算了吧..不用说了 #include & ...
- mdk3攻击实例
Authentication Flood,mdk3下参数为a: mdk3 mon0 a –a AP的MAC地址(BSSID) -c来对指定的频道进行攻击 -a固定bssid进行攻击 -s控制发包速率. ...
- ORA-12541: TNS: 无监听程序、监听程序当前无法识别连接描述符中请求的服务
%ORACLE_HOME%\product\11.2.0\dbhome_1\NETWORK\ADMIN 这个文件夹下有SAMPLE 里面有详细配置说明 有3个文件, listener.ora sqln ...
- ZSTU4269 买iphone 2017-03-22 14:31 73人阅读 评论(0) 收藏
4269: 买iphone Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1710 Solved: 316 Description 自从上次仓鼠中了 ...
- PHP全栈学习笔记19
thinkphp框架是一个免费的,开源,快速,简单的面向对象的轻量级PHP开发框架. 了解什么是thinkphp概述,thinkphp项目目录结构,thinkphp的控制器,视图,thinkphp项目 ...
- VUE 学习笔记 二 生命周期
1.除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法.它们都有前缀 $,以便与用户定义的属性区分开来 var data = { a: 1 } var vm = new Vue({ el: ' ...
- [C#学习笔记]C#中的decimal类型——《CLR via C#》
System.Decimal是非常特殊的类型.在CLR中,Decimal类型不是基元类型.这就意味着CLR没有知道如何处理Decimal的IL指令. 在文档中查看Decimal类型,可以看到它提供了一 ...
- 一次MySQL线上慢查询分析及索引使用
本文由作者郑智辉授权网易云社区发布. 0.前言 本文通过分析线上MySQL慢查询日志,定位出现问题的SQL,进行业务场景分析,结合索引的相关使用进行数据库优化.在两次处理问题过程中,进行的思考. 1. ...