AtCoder&Luogu[ABC127E] Cell Distance 题解

8 篇文章 0 订阅
7 篇文章 0 订阅

题解

我们先从小的开始,即从 2 2 2 个点开始考虑:那么两个点之间 x x x 的贡献就是 ∣ x 1 − x 2 ∣ | x_1-x_2 | x1x2,设 d d d 为这个数,那么每行就有 ( n − d ) (n-d) (nd) 个,也就是整个图有 ( n − d ) × m 2 (n-d) \times m^2 (nd)×m2 个,贡献也就是 ( n − d ) × m 2 × d (n-d)\times m^2\times d (nd)×m2×d 个;两个点之间 y y y 的贡献就是 ∣ y 1 − y 2 ∣ |y_1-y_2| y1y2,也是设这个数为 d d d,那么每列就有 ( m − d ) (m-d) (md) 个,整个图就有 ( m − d ) × n 2 (m-d) \times n^2 (md)×n2 个,贡献也就是 ( m − d ) × n 2 × d (m-d)\times n^2\times d (md)×n2×d

求出了两个点的对整个图的贡献,就下来就要考虑重复的情况了,即:
C n × m − 2 k − 2 C_{n\times m-2}^{k-2} Cn×m2k2

后面求出来这个数就可以直接乘上它就能求出贡献!

但是,又有一个问题:除数太大了!!!这时候逆元就登场了!

逆元

取模的规律如下:

  • ( a + b )   m o d   p = ( a   m o d   p + b   m o d   p )   m o d   p (a+b)\bmod p=(a\bmod p+b\bmod p)\bmod p (a+b)modp=(amodp+bmodp)modp
  • ( a − b )   m o d   p = ( a   m o d   p − b   m o d   p )   m o d   p (a-b)\bmod p=(a\bmod p-b\bmod p)\bmod p (ab)modp=(amodpbmodp)modp
  • ( a × b )   m o d   p = ( a   m o d   p × b   m o d   p )   m o d   p (a\times b)\bmod p=(a\bmod p\times b\bmod p)\bmod p (a×b)modp=(amodp×bmodp)modp

那么除法怎么办呢?

这时要想到他的逆元了:

根据费马小定理,可得出:
a b   m o d   p = ( a × b p − 2 )   m o d   p \frac{a}{b}\bmod{p}=(a\times b^{p-2})\bmod{p} bamodp=(a×bp2)modp

所以在逆元下,用个快速幂就能轻松搞定这一个题。

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1000000007;
ll n,m,k,ans=0;
ll qpow(ll a,ll b){
	ll sum = 1;
	while(b){
		if(b & 1) sum = (sum * a) % mod;
		a = (a * a) % mod;
		b >>= 1;
	} 
	return sum % mod;
}
ll C(ll a,ll b){//C(n,m)=C(n*m-2,k-2)
	if(a==b||b==0) return 1;
	if(a<b) return 0;
	ll fz=1;
	for(ll i=1;i<=a;i++)fz*=i,fz%=mod;
	ll fm=1;
	for(ll i=1;i<=b;i++)fm*=i,fm%=mod;
	ll other=1;
	for(ll i=1;i<=a-b;i++)other*=i,other%=mod;
	fm=(fm*other)%mod;
	fm=qpow(fm,mod-2)%mod;
	return (fz*fm)%mod;
}
int main(){//
	cin>>n>>m>>k;
	for(ll i=1;i<n;i++)
		ans += ((n-i)*i*m*m)%mod;
	for(ll j=1;j<m;j++)
		ans += ((m-j)*j*n*n)%mod;
	ans %= mod;
	ans=(ans*C(n*m-2,k-2))%mod;
	cout<<ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值