【JZOJ6405】【NOIP2019模拟11.04】c

题目大意

给出一个矩阵的定义:
在这里插入图片描述

求它的逆矩阵的各项平方和。

n ≤ 1000000 , m ≤ 1 0 9 + 6 n\leq 1000000,m \leq 10^9+6 n1000000,m109+6

Solution

手玩 m = 0 m=0 m=0的情况可以发现逆矩阵的定义是类似的:

  • j ≤ i , ( P n − 1 ) ( i , j ) = ( − 1 ) i + j ( j i ) j\leq i,(P^{-1}_n)(i,j)=(-1)^{i+j}(^{i}_{j}) ji,(Pn1)(i,j)=(1)i+j(ji)
  • j > i , ( P n − 1 ) ( i , j ) = 0 j>i,(P^{-1}_n)(i,j)=0 j>i,(Pn1)(i,j)=0

模拟矩阵乘法就能证明这个结论。

当多了一个 j − m j^{-m} jm时,矩阵应该是这样的:

  • j ≤ i , ( P n − 1 ) ( i , j ) = ( − 1 ) i + j ( j i ) i m j\leq i,(P^{-1}_n)(i,j)=(-1)^{i+j}(^{i}_{j})i^m ji,(Pn1)(i,j)=(1)i+j(ji)im
  • j > i , ( P n − 1 ) ( i , j ) = 0 j>i,(P^{-1}_n)(i,j)=0 j>i,(Pn1)(i,j)=0

证明与上面的类似。

于是问题变成求:
∑ i = 1 n i 2 m ∑ j = 1 i ( j i ) 2 \sum_{i=1}^{n}i^{2m}\sum_{j=1}^{i}(^i_{j})^2 i=1ni2mj=1i(ji)2

组合数的平方和即:
∑ i = 0 n C ( n , i ) 2 \sum_{i=0}^{n}C(n,i)^2 i=0nC(n,i)2
转化为:
∑ i = 0 n C ( n , i ) ∗ C ( n , n − i ) \sum_{i=0}^{n}C(n,i)*C(n,n-i) i=0nC(n,i)C(n,ni)
考虑其组合意义,相当于把一个长度为 2 n 2n 2n的序列分为两部分,枚举一部分选 i i i个,另一部分选 n − i n-i ni个。其实就是在 2 n 2n 2n个数里选 n n n个,于是上面的式子就变成:
∑ i = 1 n i 2 m ( ( i 2 i ) − 1 ) \sum_{i=1}^{n}i^{2m}((^{2i}_i)-1) i=1ni2m((i2i)1)
线性求一下逆元就能 O ( n ) O(n) O(n)解决了。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N = 2000007;
const ll P = 1e9 + 7;

int n, m;
ll ans, fac[N], inv[N];

ll pow(ll a, ll b) {
	ll ret = 1;
	for (; b; a = a * a % P, b >>= 1) if (b & 1) ret = ret * a % P;
	return ret;
}
ll C(int n, int m) { return fac[n] * inv[m] % P * inv[n - m] % P; }

int main() {
	freopen("c.in", "r", stdin);
	//freopen("c.out", "w", stdout);
	fac[0] = 1;
	for (int i = 1; i <= 2000000; ++i) fac[i] = fac[i - 1] * i % P;
	inv[0] = inv[1] = 1;
	for (int i = 2; i <= 2000000; ++i) inv[i] = inv[P % i] * (P - P / i) % P;
	for (int i = 2; i <= 2000000; ++i) inv[i] = inv[i] * inv[i - 1] % P;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) ans = (ans + pow(i, 2 * m) * (C(2 * i, i) - 1 + P) % P) % P;
	printf("%lld\n", ans);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值