首先这是个玄学的题目,很多人想到了杨辉三角,但是我太菜了于是没有想到,用了另一种方法得出了正确的式子,先写下式子好了。
求n维下m维的数量:
推理过程
我这个蒟蒻推了一节数学课才推出的结论
先来点简单的
我们生活在3维世界,很难想象出4维或4维以上世界是什么样的,但我们知道,2维可以用xy坐标表示,3维可以用xyz坐标表示,那n维就可以用n个数表示坐标,n维体就是由一些坐标构成的图形,那么坐标的数量就是0维的数量。
举个例子,二维可以表示4个坐标,分别是,三维就是,四维就是等编者好懒,不难发现,每个坐标只有两种,很容易想出维里维的个数,就是
当然如果a>=b就需要特判了啊
开始正文
观察坐标,以维为例,他的维怎么表示呢?很容易想到,如果两个点的坐标中只有一个不相同的数,那么这两个坐标间可以连一条维的线。
二维呢?还是考虑连线,所以想表示一个维怎么做?那就是连接对角线!
一个对角线一定能对应一个且仅一个维图形。对角线两个端点的坐标的性质,是有两个数不同:原因很简单,举个例子,左上到右下,有个不同因素:左右,上下;那么三维可以考虑出就多了个前后,从而推出m维就有m个因素。
那么对于维图形,从个点出发可以寻找像这样可以表示一个维图形的线段。
于是转化并简化问题:从坐标角度想,你有一个个组成的排列,问有多少含有个数且有个和个的排列。
轻松得出
诶怎么和上面的式子不太一样
然后就产生疑问了,维图形可以右下左上,左上右下,右上左下,左下右上,同一个二维图形重复计算次!那么我们考虑下,维下的维会重复计算多少次,考虑,从整个三维图形的每个点都可以向对应点发射线段,一个三维图形被重复了次(也就是三维的点的个数次),考虑维,也是从每个点数到对面都有一条线,重复次,推理出维时,这个操作将重复次,从而得出最终的式子:
至于求需要的逆元这里不多说了,很多大佬写过求逆元的博客,有事问度娘。
这是第一次写题解所以可能有点啰嗦,见谅
#include <iostream>
#include <cstdio>
#include <cmath>
typedef long long ll;
ll ans,a,b,inv[10000001];
const ll MOD=1000000007;
using namespace std;
int q_pow(ll a,ll b){
ll an=1;
while (b>0){
if (b&1)an*=a,an%=MOD;
a*=a;a%=MOD;
b>>=1;
}
return an;
}
int main(){
cin>>a>>b;
if(a<b){
printf("0");
return 0;
}
ans=q_pow(2,a-b);
inv[1]=1;
for(ll i=2;i<=100000;i++){
inv[i]=(MOD-(MOD/i))*inv[MOD%i]%MOD;
}
for(int i=1;i<=b;i++)
{
ans*=(a-i+1);ans%=MOD;
ans*=inv[i];ans%=MOD;
}
printf("%d",ans);
}
来源:CSDN
作者:zrzring
链接:https://blog.csdn.net/qq_37734034/article/details/104095967