Newcoder 145 F.Mindiff and Maxdiff(组合数学)

Description

对于一个集合 T T T,定义 m i n d i f f ( T ) mindiff(T) mindiff(T) T T T中任意两元素差值最小值, m a x d i f f ( T ) maxdiff(T) maxdiff(T) T T T中任意两元素差值最大值,如果集合元素少于两个则定义两者值为 0 0 0. 对集合 { 1 , 2 , . . . , n } \{1,2,...,n\} {1,2,...,n}的所有子集 T T T m i n d i f f ( T ) ⋅ m a x d i f f ( T ) mindiff(T)\cdot maxdiff(T) mindiff(T)maxdiff(T)求和

Input

一个整数 n ( 1 ≤ n ≤ 5 ⋅ 1 0 5 ) n(1\le n\le 5\cdot 10^5) n(1n5105)

Output

输出答案,结果模 1 0 9 + 7 10^9+7 109+7

Sample Input

3

Sample Output

8

Solution

m n ( T ) mn(T) mn(T)为集合 T T T中任意两元素差值最小值, m x ( T ) mx(T) mx(T)为集合 T T T中任意两元素差值最大值,对于集合 T T T,假设其 m n ( T ) = d mn(T)=d mn(T)=d,那么 m x ( T ) mx(T) mx(T)对答案的贡献是 d d d倍,进而考虑所有 m n ( S ) ≥ d mn(S)\ge d mn(S)d的集合 S S S m x mx mx值之和,那么 m x ( T ) mx(T) mx(T) m x ( S ) ≥ 1 , . . . , d mx(S)\ge 1,...,d mx(S)1,...,d时都会被算一遍,也即算了 d d d遍,故答案为 ∑ d = 1 n − 1 f ( d ) \sum\limits_{d=1}^{n-1}f(d) d=1n1f(d),其中 f ( d ) f(d) f(d)为所有 m n ( S ) ≥ d mn(S)\ge d mn(S)d的集合 S S S m x mx mx值之和,现在求 f ( d ) f(d) f(d),枚举集合 T T T的元素个数 k k k m x ( T ) = t mx(T)=t mx(T)=t,那么在 1 1 1~ n n n中选出最小值和最大值使得两者差值为 t t t的方案数为 n − t n-t nt种,而在两者之间的 t − 1 t-1 t1个位置中,为保证任意两个数字之间距离不小于 d − 1 d-1 d1,由插板法,提前拿出 ( k − 1 ) ( d − 1 ) (k-1)(d-1) (k1)(d1)个位置空着,在剩余位置中选取 k − 2 k-2 k2个位置放剩下数字,故有
f ( d ) = ∑ k = 2 n ∑ t = 1 n − 1 t ( n − t ) C t − 1 − ( k − 1 ) ( d − 1 ) k − 2 f(d)=\sum\limits_{k=2}^n\sum\limits_{t=1}^{n-1}t(n-t)C_{t-1-(k-1)(d-1)}^{k-2} f(d)=k=2nt=1n1t(nt)Ct1(k1)(d1)k2
注意到为使组合数合法,需要修改 k , d k,d k,d的下限,进而有
f ( d ) = ∑ ( k − 1 ) d ≤ n ∑ t = ( k − 1 ) d n − 1 t ( n − t ) C t − 1 − ( k − 1 ) ( d − 1 ) k − 2 f(d)=\sum\limits_{(k-1)d\le n}\sum\limits_{t=(k-1)d}^{n-1}t(n-t)C_{t-1-(k-1)(d-1)}^{k-2} f(d)=(k1)dnt=(k1)dn1t(nt)Ct1(k1)(d1)k2
由于满足 ( k − 1 ) d ≤ n (k-1)d\le n (k1)dn ( k , d ) (k,d) (k,d)组数只有 O ( n l o g n ) O(nlogn) O(nlogn)规模,只需快速求出
∑ t = ( k − 1 ) d n − 1 t ( n − t ) C t − 1 − ( k − 1 ) ( d − 1 ) k − 2 \sum\limits_{t=(k-1)d}^{n-1}t(n-t)C_{t-1-(k-1)(d-1)}^{k-2} t=(k1)dn1t(nt)Ct1(k1)(d1)k2
m a t h e m a t i c a mathematica mathematica里跑一下有
∑ t = ( k − 1 ) d n − 1 t ( n − t ) C t − 1 − ( k − 1 ) ( d − 1 ) k − 2 = ( n − 1 + 2 d ) ( n − ( k − 1 ) d ) ( n − ( k − 1 ) ( d − 1 ) ) k ( k + 1 ) C n − 1 − ( k − 1 ) ( d − 1 ) k − 2 \sum\limits_{t=(k-1)d}^{n-1}t(n-t)C_{t-1-(k-1)(d-1)}^{k-2}=\frac{(n-1+2d)(n-(k-1)d)(n-(k-1)(d-1))}{k(k+1)}C_{n-1-(k-1)(d-1)}^{k-2} t=(k1)dn1t(nt)Ct1(k1)(d1)k2=k(k+1)(n1+2d)(n(k1)d)(n(k1)(d1))Cn1(k1)(d1)k2
故可以 O ( 1 ) O(1) O(1)求出该求和式,总时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

Code

#include<cstdio>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f,maxn=500005;
#define mod 1000000007 
int inv[maxn],fact[maxn],sum[maxn];
int add(int x,int y)
{
	x+=y;
	if(x>=mod)x-=mod;
	return x;
}
int mul(int x,int y)
{
	ll z=1ll*x*y;
	return z-z/mod*mod;
}
void init(int n=500001)
{
	inv[1]=1;
	for(int i=2;i<=n;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
	sum[0]=1;
	for(int i=1;i<=n;i++)sum[i]=mul(sum[i-1],inv[i]);
	fact[0]=1;
	for(int i=1;i<=n;i++)fact[i]=mul(fact[i-1],i);
}
int C(int n,int m)
{
	if(n<0||m<0||m>n)return 0;
	return mul(fact[n],mul(sum[m],sum[n-m]));
}
int main()
{
	init();
	int n;
	scanf("%d",&n);
	int ans=0;
	for(int d=1;d<=n-1;d++)
		for(int k=2;(k-1)*d<=n&&k<=n;k++)
		{
			int w=n-(k-1)*(d-1);
			int res=C(w-1,k-2);
			res=mul(mul(res,n-1+2*d),mul(inv[k],inv[k+1]));
			res=mul(res,mul(w-(k-1),w));
			ans=add(ans,res);
		}
	printf("%d\n",ans);
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值