lg1999高维正方体

链接:lg1999高维正方体

Description

  • 0维空间的元素是点,这个毋庸置疑。
  • 2个0维空间的元素可以围成一个1维空间的元素,线段。
  • 4个1维空间的元素可以围成一个2维空间的元素,正方形。
  • 6个2维空间的元素可以围成一个3维空间的元素,正方体。
  • 8个3维空间的元素可以围成一个4维空间的元素,超正方体。
  • ……
  • 一个正方形中,有4个(顶)点,4条线段(边),1个正方形。
  • 一个正方体中,有8个(顶)点,12条线段(棱),6个正方形(面),1个正方体。
  • ……
  • 我们的问题是:给出a与b,请求出:在a维空间的元素中,包含着多少个b维空间的元素。答案可能很大,只需要输出它除以1000000007
  • 的余数。

    Input

  • 两个整数a,b,以空格隔开。

    Output

  • 一个整数,即答案。

    Sample Input

    3 1

    Sample Output

    12

    题解

  • 找规律,答案等于C(a,b)*pow(2,(a-b))
  • a,b很大,组合数直接做肯定爆ll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
const ll mod=1000000007;
const int N=1e6+7;
ll n,m,inv[N];

inline void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){x=1; y=0;}
else {
exgcd(b,a%b,x,y);
ll t=x;x=y;y=t-a/b*x;
}
}

ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;b>>=1;
}
return ans;
}

ll cal(){
ll t,ans=1;
rep(i,1,m){exgcd(i,mod,inv[i],t); inv[i]=inv[i]<=0?(inv[i]+mod)%mod:inv[i];}
rep(i,1,m)ans=(ans%mod*inv[i]%mod*(n-m+i))%mod;
return ans;
}


int main(){
scanf("%lld%lld",&n,&m);
if(n<m)printf("0\n");
else printf("%lld\n",cal()*qpow(2,n-m)%mod);
//cout<<cal()<<' '<<qpow(2,n-m)%mod;
return 0;
}