Dandelion(卡特兰数+费马小定理求逆元)

5 篇文章 0 订阅
3 篇文章 0 订阅

题目链接:http://whu2019.contest.codeforces.com/group/YyBKO8xFiH/contest/102167/problem/D

D. Dandelion

time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

"O dandelion, yellow as gold,

What do you do all day?"

"I just wait here in the tall green grass

Till the children come to play."

"O dandelion, yellow as gold,

What do you do all night?"

"I wait and wait till the cool dews fall

And my hair grows long and white."

"And what do you do when your hair is white

And the children come to play?"

"They take me up in their dimpled hands

And blow my hair away!"

Spring is here and the dandelion is blooming. There is a small dandelion seed taking off. It will float upwards when there is no wind, and when the wind blows up it will be blown to the right.

In other words, if a dandelion seed is currently at point (x,y), the next second it will only appear in either point (x,y+1) or point (x+1,y). All points (x,y) on the path must satisfy the constraint that x is less than y(i.e x<y.

Now, there is a dandelion seed at point (0,0), please find the number of ways(mod 109+7) to reach the point (m,n). 0<m<n≤100000.

Input

The first line has a integer T (T<10), it means the number of the case.

The following lines of input will be two integers: mm and nn.

Output

For each case, print an integer in a single line to represent the answer.

Example

input

Copy

3
3 4
4 5
999 1000

output

Copy

5
14
894965608

题意:求从(0,0)到(m,n)一共有多少种走法(要求:对于每一个坐标(x,y),x要小于y)

 

卡特兰数模板及典型应用https://blog.csdn.net/zuzhiang/article/details/77966726

本题考的是卡特兰数的一个变形,先看一个简单的问题

 n+m个人排队买票,并且满足,票价为50元,其中n个人各手持一张50元钞票,m个人各手持一张100元钞票,初始时候售票窗口没有钱,问有多少种排队的情况数能够让大家都买到票。

如果m=n的话那么这就是初始的Catalan数问题,也就是将手持50元的人看成是+1,手持100元的人看成是-1,任前k个数值的和都非负的序列数。

对于n>m的情况,假设大家都可以买到票的情况数是ans,无法让每个人都买到的情况数是cnt,那么就有ans+cnt=C(n+m,n),假设最早买不到票的人编号是k,他手持的是100元并且售票处没有钱,那么将前k个人的钱从50元变成100元,从100元变成50元,这时候就有n+1个人手持50元,m-1个手持100元的,所以就得到cnt=C(n+m,n+1),同时ans=C(n+m,n)-C(n+m,n+1)。

 

看完这个问题应该会有一点思路,甚至会觉得答案不就是C(n+m,n)-C(n+m,n+1)吗,但是通过这个式子算出来的结果和答案并不一样,为什么呢?

上面那个问题里的要求是对于每一个(x,y),要求x<=y,  但是本题的要求是x<y,那怎么办?

很容易想到,第一步只能是向上走(y+1),所以我们把第一步拿出来,只要后面每一个(x,y)满足x<=y,那么总的不就满足x<y了吗,题目也就转化成了求从(0,0)到(m,n-1)一共有多少种走法(要求:对于每一个坐标(x,y),x要小于等于y)

所以答案是ans = C(n+m-1,m) - C(n+m-1,m-1)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<list>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int mod=1e9+7; 
ll ksm(ll a,ll b){
	ll s=1;
	while(b){
		if(b&1){
			a%=mod;
			s%=mod;
			s*=a;
		}
		a%=mod;
		a*=a;
		b>>=1;
	}
	return s%mod;
}
ll solve(ll n,ll m){ //c(n,m)
    if(m==0) return 1LL;
	if(m>n-m) m=n-m;
	ll a=1,b=1;//分子,分母
	for(int i=1;i<=m;i++){
		a=(a*(n-i+1))%mod;
		b=(b*i)%mod;
	}
	return a*ksm(b,mod-2)%mod;	
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
    	ll n,m;
    	scanf("%lld%lld",&m,&n);
    	printf("%lld\n",(solve(n+m-1,m)-solve(n+m-1,m-1)+mod)%mod);
	}
	return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dandelion-optimizer是一种基于多样性优化技术的优化算法。在解决优化问题时,传统的算法往往陷入局部最优解的困境,而dandelion-optimizer通过引入多样性,能够更好地搜索全局最优解。 dandelion-optimizer的原理类似于蒲公英的传播方式。在蒲公英花朵中,种子会从母本花朵的果穗中脱离,通过风的力量进行传播。在优化问题中,种子代表解空间的候选解,而风则表示优化的方向。dandelion-optimizer通过种子的传播和风的力量相结合,来改善搜索过程。 具体来说,dandelion-optimizer首先初始化一组随机解,即种子。然后,通过计算适应度函数来评估每个种子的优劣。接下来,算法会根据适应度值选择一些优秀的种子作为"母本",同时根据一定规则生成一些新的解作为"子代"。这样,种子就会根据它们的适应度被推动到更好的解空间中。 而为了引入多样性,dandelion-optimizer会在每一代中引入一些随机解,即通过"风"的力量随机传播的种子。这样一来,算法就能够避免陷入局部最优解,并尽可能地搜索全局最优解。 总的来说,dandelion-optimizer是一种能够通过多样性优化技术来改善优化问题搜索的算法。它通过引入种子的传播和风的力量来提高解空间的搜索效率,并且能够避免陷入局部最优解。通过这种方式,dandelion-optimizer能够更好地找到全局最优解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值