BZOJ3601. 一个人的数论(狄利克雷卷积+高斯消元)及关于「前 $n$ 个正整数的 $k$ 次幂之和是关于 $n$ 的 $k+1$ 次多项式」的证明
题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3601
题解
首先还是基本的推式子:
\]
令 \(g(x) = \sum_\limits{i = 1}^x i^d\),那么原式即为 $ \sum_\limits{k |n} \mu(k)k^d g(\frac{n}{k})$。
关于函数 \(g(x)\),这其实是一个关于 \(x\) 的 \(d + 1\) 次多项式。在这里我们作简要证明。也就是我们要证明「前 \(n\) 个正整数的 \(k\) 次幂之和是关于 \(n\) 的 \(k+1\) 次多项式」。这里把我之前的一篇博客中的内容放出来。证明如下:
令 \(S(n, k) = \sum_\limits{i = 1}^{n} i^k\),那么我们的目的无非是要证明 \(S(n, k)\) 与一个关于 \(n\) 的 \(k + 1\) 次多项式存在某种等式关系。我们作如下考虑:
- 我们将两个关于 \(n\) 的 \(k + 1\) 次多项式 \((n + 1)^{k + 1}\) 与 \(n^{k + 1}\) 相减,得到: $$\begin{aligned}(n + 1)^{k + 1}-n^{k + 1} &= \left(\sum_{i = 0}^{k + 1}{\binom{k + 1}{i}}n^i\right) - n^{k + 1} \ &= \sum_{i = 0}^k\binom{k + 1}{i}n^i \end{aligned}$$ 其中,\((n + 1)^{k + 1} = \sum_\limits{i = 0}^{k + 1}\binom{k + 1}{i}n^i\) 用到了二项式定理。
- 多项式 \(n^{k + 1}\)与 \((n - 1)^{k + 1}\) 相减,得到: $$n^{k + 1} - (n - 1)^{k + 1} = \sum_{i = 0}^k \binom{k + 1}{i}(n - 1)^i$$
- \(\cdots\)
- 多项式 \(1^{k + 1}\) 与 \(0^{k + 1}\) 相减,得到 $$1^{k + 1} - 0^{k + 1} = \sum_{i = 0}^k\binom{k + 1}{i}0^i$$
- 将上面所有式子相加,得到 $$(n + 1)^{k + 1} = \sum_{i = 0}^{k}\binom{k + 1}{i}S(n, i)$$
当 \(k = 0\) 时,\(S(n, 0)\) 显然是一个关于 \(n\) 的 \(1\) 次多项式。通过移项,即可得到:对于任意的 \(k(k > 0)\),均满足 \(S(n, k)\) 是一个关于 \(n\) 的 \(k + 1\) 次多项式。
同时,我们还能推广该结论得到:若 \(f(x)\) 是一个关于 \(x\) 的任意 \(k\) 次多项式,\(g(x)\) 满足 \(g(x) = \sum_\limits{i = 1}^{x} f(i)\),那么 \(g(x)\) 也是一个关于 \(x\) 的 \(k + 1\) 次多项式。
其证明显然,我们只需要将 \(f(i)\) 的各次项拆开统计到 \(g(x)\) 中,那么 \(g(x)\) 就是 \(k + 1\) 个形如 \(a \sum_\limits{i = 1}^{x}i^b (0 \leq b \leq k)\) 的关于 \(x\) 的 \(b + 1\) 次多项式的和,即关于 \(x\) 的 \(k + 1\) 次多项式。
既然 \(g(x)\) 已经是一个关于 \(x\) 的 \(d + 1\) 次多项式,那么我们就可以将 \(g(x)\) 写成多项式的一般形式,即:\(g(x) = \sum_\limits{i = 0}^{d + 1}a_{i}x^i\)。由于 \(d \leq 100\),因此每一项的系数 \(a_i\) 可以通过高斯消元求得,复杂度是可接受的。我们将 \(g(x)\) 代入原答案式,得到:
\]
令 \(h_i(x) = \sum_\limits{k | x} \mu(k) k^d \left(\frac{x}{k}\right)^i\),显然,\(h_i\) 是两个积性函数的狄利克雷卷积。因此 \(h_i\) 本身也是一个积性函数,由于 \(n\) 的唯一分解式为 \(n = \prod_\limits{k = 1}^{w} p_k ^{\alpha_k}\),故有 \(h_i(n) = \prod_\limits{k = 1}^w h_i(p_k^{\alpha_k})\)。
考虑如何求单个 \(h_i(p ^{\alpha})\):
\]
由于当 \(j = 0\) 时,\(\mu(p^j) = 1\);当 \(j = 1\) 时,\(\mu(p^j) = -1\);当 \(j > 1\) 时,\(\mu(p^j) = 0\)。故有:
\]
这样,单个 \(h_i(p ^ {\alpha})\) 就能用快速幂在 \(O(\log \alpha)\) 的时间内求出。因此,解决整个问题的时间复杂度为 \(O(d^3 + dw \log \alpha)\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, mod = 1e9 + 7;
void add(int& x, int y) {
  x += y;
  if (x >= mod) {
    x -= mod;
  }
}
void sub(int& x, int y) {
  x -= y;
  if (x < 0) {
    x += mod;
  }
}
int mul(int x, int y) {
  return (long long) x * y % mod;
}
int qpow(int v, int p) {
  int result = 1;
  for (; p; p >>= 1, v = mul(v, v)) {
    if (p & 1) {
      result = mul(result, v);
    }
  }
  return result;
}
int d, w, p[N], alpha[N], a[N][N];
void get_coefficient() {
  int sum = 0;
  for (int i = 0; i <= d + 1; ++i) {
    add(sum, qpow(i, d));
    a[i][d + 2] = sum;
    int pow_value = 1;
    for (int j = 0; j <= d + 1; ++j) {
      a[i][j] = pow_value;
      pow_value = mul(pow_value, i);
    }
  }
  for (int i = 0; i <= d + 1; ++i) {
    int rev = i;
    for (int j = i + 1; j <= d + 1; ++j) {
      if (a[j][i]) {
        rev = j;
        break;
      }
    }
    if (rev != i) {
      for (int j = i; j <= d + 2; ++j) {
        swap(a[rev][j], a[i][j]);
      }
    }
    for (int j = i + 1; j <= d + 1; ++j) {
      int p = mul(a[j][i], qpow(a[i][i], mod - 2));
      for (int k = i; k <= d + 2; ++k) {
        sub(a[j][k], mul(a[i][k], p));
      }
    }
  }
  for (int i = d + 1; ~i; --i) {
    for (int j = i + 1; j <= d + 1; ++j) {
      sub(a[i][d + 2], mul(a[i][j], a[j][d + 2]));
    }
    a[i][d + 2] = mul(a[i][d + 2], qpow(a[i][i], mod - 2));
  }
}
int g(int i, int j) {
  int p_i = p[j], alpha_i = alpha[j];
  int c1 = (long long) alpha_i * i % (mod - 1);
  int c2 = (c1 + d - i + mod - 1) % (mod - 1);
  return (qpow(p_i, c1) - qpow(p_i, c2) + mod) % mod;
}
int main() {
  scanf("%d%d", &d, &w);
  get_coefficient();
  for (int i = 1; i <= w; ++i) {
    scanf("%d%d", &p[i], &alpha[i]);
  }
  int answer = 0;
  for (int i = 0; i <= d + 1; ++i) {
    int result = a[i][d + 2];
    for (int j = 1; j <= w; ++j) {
      result = mul(result, g(i, j));
    }
    add(answer, result);
  }
  printf("%d\n", answer);
  return 0;
}
BZOJ3601. 一个人的数论(狄利克雷卷积+高斯消元)及关于「前 $n$ 个正整数的 $k$ 次幂之和是关于 $n$ 的 $k+1$ 次多项式」的证明的更多相关文章
- [bzoj3601] 一个人的数论 [莫比乌斯反演+高斯消元]
		题面 传送门 思路 这题妙啊 先把式子摆出来 $f_n(d)=\sum_{i=1}^n[gcd(i,n)==1]i^d$ 这个$gcd$看着碍眼,我们把它反演掉 $f_n(d)=\sum_{i=1}^ ... 
- 【bzoj3601】一个人的数论  莫比乌斯反演+高斯消元
		题目描述 题解 莫比乌斯反演+高斯消元 (前方高能:所有题目中给出的幂次d,公式里为了防止混淆,均使用了k代替) #include <cstdio> #include <cstrin ... 
- BZOJ 3601 一个人的数论 ——莫比乌斯反演 高斯消元
		http://www.cnblogs.com/jianglangcaijin/p/4033399.html ——lych_cys 我还是太菜了,考虑一个函数的值得时候,首先考虑是否积性函数,不行的话就 ... 
- JSOI球形空间产生器 (高斯消元)
		按照朴素的列方程,可以列出n+1个n元2次方程. 将相邻的两个方程相减就可以得到n个n元1次方程,进行高斯消元就可以了. ..,..] of extended; temp,ans:..] of ext ... 
- BZOJ 3270 博物馆 ——概率DP 高斯消元
		用$F(i,j)$表示A在i,B在j的概率. 然后很容易列出转移方程. 然后可以高斯消元了! 被一个问题困扰了很久,为什么起始点的概率要加上1. (因为其他博客上都是直接写成-1,雾) 考虑初始状态是 ... 
- BZOJ3601 一个人的数论  【数论 + 高斯消元】
		题目链接 BZOJ3601 题解 挺神的 首先有 \[ \begin{aligned} f(n) &= \sum\limits_{x = 1}^{n} x^{d} [(x,n) = 1] \\ ... 
- 【bzoj3601】一个人的数论 莫比乌斯反演+莫比乌斯函数性质+高斯消元
		Description Sol 这题好难啊QAQ 反正不看题解我对自然数幂求和那里是一点思路都没有qwq 先推出一个可做一点的式子: \(f(n)=\sum_{k=1}^{n}[(n,k)=1]k^d ... 
- 【BZOJ3601】一个人的数论 高斯消元+莫比乌斯反演
		[BZOJ3601]一个人的数论 题解:本题的做法还是很神的~ 那么g(n)如何求呢?显然它的常数项=0,我们可以用待定系数法,将n=1...d+1的情况代入式子中解方程,有d+1个方程和d+1个未知 ... 
- BZOJ-1013   球形空间产生器sphere     高斯消元+数论推公式
		1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3662 Solved: 1910 [Subm ... 
随机推荐
- 使用GPUImage渲染图片教程
			使用GPUImage渲染图片教程 Prepare - 准备 GPUImage开源库并不像普通的开源库那样子,拖进你的工程中就可以用.以下将详细的告诉你如何将GPUImage导入到你的工程当中. 首先上 ... 
- [翻译] DraggableYoutubeFloatingVideo
			DraggableYoutubeFloatingVideo DraggableYoutubeFloatingVideo allows you to play videos on a floating ... 
- Office 365实现单点登录系列(5)—配置单点登录
			这是单点登录系列的最后一篇文章,前面4篇文章其实都是在为这篇文章的内容做准备,我把这四篇文章的链接放在下面,如果大家有需要,可以参考我以下的链接: Office 365实现单点登录系列(1)—域环境搭 ... 
- 多数据源报错  expected single matching bean but found 2: xxx,xxx
			问题: expected single matching bean but found 2: xxx,xxx 原因:在 Spring 容器中配置了两个类型Bean,Spring 容器将无法确定到底要用 ... 
- HashMap集合特点
			>HashMap集合特点 HashMap:是基于哈希表的Map接口实现. 哈希表的作用是用来保证键的唯一性的. 不明白,直接看HashMap的put方法源码 //HashM ... 
- zabbix对网卡流量超出添加阈值
			给网卡设置流量阈值: 配置告警路径: Configuration--Templates--Template OS Linux--Discovery--Network interface discove ... 
- lambda表达式和groovy闭包的区别
			groovy定义的闭包是 Closure 的实例,lambda表达式只是在特定的接⼝或者抽象类的匿名实现,他们之间最主要区别闭包可以灵活的配置代理策略⽽labmda表达式不允许 
- python处理数据(二)
			处理PDF文件 PyPDF2简介 作为 PDF 工具包构建的纯 python 库. 它可以:提取文档信息(标题,作者,... ...)一页一页地分割文件一页一页地合并文件裁剪页面将多个页面合并成一个页 ... 
- 【洛谷】【lca+结论】P3398 仓鼠找sugar
			[题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ... 
- etherlime-4-Etherlime CLI
			Etherlime CLI命令行界面 Installing & Help Syntax语法 npm i -g etherlime Install the global etherlime to ... 
