51nod1847 奇怪的数学题 (Min_25筛+第二类斯特林数)

时间:2022-08-26 21:26:21

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(i,j)=p]=\sum_{p=1}^ns(p)^k(-1+2\sum_{i=1}^{n/p}\varphi(i))\)

由于 \(n\) 的范围是 \(10^9\) ,对于后面的我们最多只有根号种取值,根据套路,可以杜教筛/Min_25筛一波。

至于前面的东西,我们可以考虑Min_25筛的过程:

Min_25筛我们设 \(g(n,j)\) 为2~n内素数或最小质因子\(\ge p_j\)的数的\(k\)次方的和

考虑转移:

\(g(n,j)=g(n,j-1)-p_j^k(g(a/p_j,j-1)-g(p_{j-1},j-1)) (n\ge p_j^2)\)

我们发现后面减去的 \(p_j^k(g(a/p_j,j-1)-g(p_{j-1},j-1))\) 就是最小质因子恰为 \(p_j\) 的合数的k次方的和

那么 \(g(a/p_j,j-1)-g(p_{j-1},j-1)\) 就是[1, n]内这最小质因子为 \(p_j\) 的合数的 \(s(x)^k\) 的和。

我们对于每个n/x向下取整开一个数,记录每个 j 的这个值,然后差分一下就是区间的答案了。(注意加上质数的贡献,也就是区间质数个数)

预处理Min_25筛的数组时,由于模数是合数,所以不能拉格朗日插值,要用第二类斯特林数:

\(\sum_{i=1}^ni^k=\sum_{i=1}^n\sum_{j=0}^k\{^k_j\}{i\choose j}j!=\sum_{j=0}^k\{^k_j\}j!\sum_{i=1}^n{i\choose j}=\sum_{j=0}^k\{^k_j\}j!{n+1\choose j+1}=\sum_{j=0}^k\{^k_j\}\frac{n+1^{\underline{j+1}}}{j+1}\)

phi用Min_25筛的代码:(观察txc巨佬的)

#include <cstdio>
#include <cmath>
#define int unsigned
using namespace std; int n, m, k, sqt, tot;
int a[233333], g0[233333], g1[233333], gk[233333], gphi[233333], ans[233333], prime[233333], s[233][233];
int getid(int x) { return x <= sqt ? x : m - n / x + 1; } int qsum(int n)
{
int ans = 0;
for (int i = 0; i <= k; i++)
{
int tmp = 1;
for (int j = 0; j <= i; j++) //(n - j + 1)
if ((n - j + 1) % (i + 1) == 0) tmp *= ((n - j + 1) / (i + 1));
else tmp *= (n - j + 1);
ans += tmp * s[k][i];
}
return ans;
}
signed main()
{
scanf("%u%u", &n, &k), sqt = sqrt(n);
s[0][0] = 1;
for (int i = 1; i <= k; i++) for (int j = 1; j <= i; j++) s[i][j] = s[i - 1][j] * j + s[i - 1][j - 1];
for (int i = 1; i <= n; i = a[m] + 1)
{
a[++m] = n / (n / i);
gk[m] = qsum(a[m]) - 1;
g1[m] = a[m] * (long long)(a[m] + 1) / 2 - 1;
g0[m] = a[m] - 1;
}
for (int i = 1; i <= sqt; i++) if (g0[i] != g0[i - 1])
{
prime[++tot] = i;
int tmp = 1;
for (int t = 1; t <= k; t++) tmp *= i;
for (int j = m; a[j] >= i * i; j--)
{
int id = getid(a[j] / i);
gk[j] -= tmp * (gk[id] - gk[i - 1]);
ans[j] += gk[id] - gk[i - 1];
g1[j] -= i * (g1[id] - g1[i - 1]);
g0[j] -= g0[id] - g0[i - 1];
}
}
for (int i = 1; i <= m; i++) gphi[i] = (g1[i] -= g0[i]);
for (int i = tot; i >= 1; i--)
for (int j = m; a[j] >= prime[i] * prime[i]; j--)
for (int x = prime[i], f = x - 1; x * (long long)prime[i] <= a[j]; x *= prime[i], f *= prime[i])
gphi[j] += f * (gphi[getid(a[j] / x)] - g1[prime[i]] + prime[i]);
int res = 0;
for (int i = 2; i <= m; i++) res += (ans[i] - ans[i - 1] + g0[i] - g0[i - 1]) * (2 * gphi[m - i + 1] + 1);
printf("%u\n", res);
return 0;
}

phi用杜教筛写的代码:

#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std; #define int unsigned int n, k, sqt;
int a[233333], g0[233333], gk[233333], prime[233333], ans[233333], tot, m;
int s[60][60];
int phi[233333], mem[233333];
bool vis[233333]; int qid(int x) { return x <= sqt ? x : m - n / x + 1; } int qsum(int x, int k)
{
int ans = 0;
for (int i = 0; i <= k; i++)
{
int tmp = 1;
for (int j = 0; j <= i; j++)
{
if ((x + 1 - j) % (i + 1) == 0) tmp *= (x + 1 - j) / (i + 1);
else tmp *= x + 1 - j;
}
ans += tmp * s[k][i];
}
return ans;
} int chuphi(int id)
{
if (a[id] <= sqt) { return phi[a[id]]; }
if (mem[id] != 0xffffffff) return mem[id];
int n = a[id], ans = n * (n + 1) / 2;
for (int i = 2; i <= n; i = n / (n / i) + 1)
ans -= chuphi(qid(n / i)) * (n / (n / i) - i + 1);
return mem[id] = ans;
} signed main()
{
memset(mem, 0xff, sizeof(mem)); phi[1] = 1;
scanf("%u%u", &n, &k), sqt = sqrt(n);
s[0][0] = 1;
for (int i = 1; i <= k; i++) for (int j = 1; j <= k; j++) s[i][j] = s[i - 1][j - 1] + j * s[i - 1][j];
for (int i = 1; i <= n; i = a[m] + 1)
{
a[++m] = n / (n / i);
g0[m] = a[m] - 1;
gk[m] = qsum(a[m], k) - 1;
}
for (int i = 1; i <= sqt; i++)
{
if (g0[i] != g0[i - 1])
{
prime[++tot] = i, phi[i] = i - 1;
int tmp = 1; for (int j = 1; j <= k; j++) tmp *= i;
for (int j = m; a[j] >= i * i; j--)
{
int id = qid(a[j] / i);
g0[j] -= g0[id] - g0[i - 1];
gk[j] -= tmp * (gk[id] - gk[i - 1]);
ans[j] += gk[id] - gk[i - 1];
}
}
for (int j = 1; j <= tot && i * prime[j] <= sqt; j++)
{
if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; }
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
phi[i] += phi[i - 1];
}
int res = 0;
for (int i = 1; i <= m; i++)
{
res += (ans[i] - ans[i - 1] + g0[i] - g0[i - 1]) * (2 * chuphi(m - i + 1) - 1);
}
printf("%u\n", res);
return 0;
}

51nod1847 奇怪的数学题 (Min_25筛+第二类斯特林数)的更多相关文章

  1. 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min&lowbar;25筛,第二类斯特林数)

    [51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...

  2. 【51NOD1847】奇怪的数学题 min&lowbar;25筛

    题目描述 记\(sgcd(i,j)\)为\(i,j\)的次大公约数. 给你\(n\),求 \[ \sum_{i=1}^n\sum_{j=1}^n{sgcd(i,j)}^k \] 对\(2^{32}\) ...

  3. 【BZOJ2159】Crash的文明世界(第二类斯特林数,动态规划)

    [BZOJ2159]Crash的文明世界(第二类斯特林数,动态规划) 题面 BZOJ 洛谷 题解 看到\(k\)次方的式子就可以往二项式的展开上面考,但是显然这样子的复杂度会有一个\(O(k^2)\) ...

  4. BZOJ 2159&colon; Crash 的文明世界&lpar;组合数学&plus;第二类斯特林数&plus;树形dp&rpar;

    传送门 解题思路 比较有意思的一道数学题.首先\(n*k^2\)的做法比较好想,就是维护一个\(x^i\)这种东西,然后转移的时候用二项式定理拆开转移.然后有一个比较有意思的结论就是把求\(x^i\) ...

  5. 【BZOJ5093】图的价值(第二类斯特林数,组合数学,NTT)

    [BZOJ5093]图的价值(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 单独考虑每一个点的贡献: 因为不知道它连了几条边,所以枚举一下 \[\sum_{i=0}^{n-1}C_{n-1 ...

  6. 【BZOJ4555】求和(第二类斯特林数,组合数学,NTT)

    [BZOJ4555]求和(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 推推柿子 \[\sum_{i=0}^n\sum_{j=0}^iS(i,j)·j!·2^j\] \[=\sum_{i= ...

  7. CF932E Team Work(第二类斯特林数)

    传送门:CF原网 洛谷 题意:给定 $n,k$,求 $\sum\limits^n_{i=1}\dbinom{n}{i}i^k\bmod(10^9+7)$. $1\le n\le 10^9,1\le k ...

  8. HDU - 4625 JZPTREE(第二类斯特林数&plus;树DP)

    https://vjudge.net/problem/HDU-4625 题意 给出一颗树,边权为1,对于每个结点u,求sigma(dist(u,v)^k). 分析 贴个官方题解 n^k并不好转移,于是 ...

  9. 【CF961G】Partitions 第二类斯特林数

    [CF961G]Partitions 题意:给出n个物品,每个物品有一个权值$w_i$,定义一个集合$S$的权值为$W(S)=|S|\sum\limits_{x\in S} w_x$,定义一个划分的权 ...

随机推荐

  1. 基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现

    在一个系统里面,往往有很多菜单项目,每个菜单项对应一个页面,一般用户只需要用到一些常用的功能,如果每次都需要去各个层次的菜单里面去找对应的功能,那确实有点繁琐.特别是在菜单繁多,而客户又对系统整体不熟 ...

  2. java中与数据库的连接

    package unitl01; import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet; ...

  3. Windows消息传递机制详解

    Windows是一个消息(Message)驱动系统.Windows的消息提供了应用程序之间.应用程序与Windows系统之间进行通信的手段.应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理 ...

  4. python-函数中定义可变参数

    可变参数 在Python函数中,还可以定义可变参数.顾名思义,可变参数就是传入的参数个数是可变的,可以是1个.2个到任意个,还可以是0个. 我们以数学题为例子,给定一组数字a,b,c……,请计算a2 ...

  5. Graph database&lowbar;neo4j 底层存储结构分析&lpar;8&rpar;

    3.8  示例1:neo4j_exam 下面看一个简单的例子,然后看一下几个主要的存储文件,有助于理解<3–neo4j存储结构>描述的neo4j 的存储格式. 3.8.1    neo4j ...

  6. iOS开发 画六边形&lpar;多边形&rpar;

    - (void)drawRect:(CGRect)rect { UIBezierPath * path = [UIBezierPath bezierPath]; [path moveToPoint:C ...

  7. Bash简介

    Bash(GNU bourne-Again Shell)是一个为GNU计划编写的Unix shell,它是很多Linux平台默认的使用的shell. shell是一个命令解析器,是介于操作系统内核与用 ...

  8. c&num;获取机器唯一识别码

    前言 在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为MAC地址是不会变的,但是现在各种改,特别是使用无线上网卡,MAC地址插一次变一次,所以这样使用MAC就没有什么意义了,怎么办,又 ...

  9. Cent OS5&period;2安装Hyper-V集成光盘

    一.Hyper-V安装windows系统没有问题,windows2000以后系统都可以,一切顺利. 驱动程序:IDE.SCSI.网络.视频和鼠标 要想实现更强的功能,宿主机需要安装Hyper-V集成光 ...

  10. &lbrack;原创&rsqb;obj-c编程16&colon;键值编码&lpar;KVC&rpar;

    原文链接:obj-c编程16:键值编码(KVC) 我们可以借助obj-c中的键值编码(以后简称KVC,Key-Value Coding)来存取类的属性,通过指定所要访问的属性名字符串标示符,可以使用存 ...