隔板法
开始找了个规律,话说还真有。。。不过n有10^9次。。。就各种爆。。。这里就只能用显示公式做了
题意:n=1+1+... 或 n=1+2+... 问所有n的等式中,k在右边出现的次数
if(k>n)break
然后就是高中的隔板法。。。 ex. n=8,k=3
1、从8个点中选取3个点 ,则剩下的隔板有 (n-1)-(k+1)=n-k-2个隔板 隔板选法有 2^(n-k-2)种。。。
//看了题解发现这里要再乘一个 (n-k-1) 因为这个等式k这个数只点了一次,相当于点出所有k在此位置的个数
2、取到边界共左右2种,各有 n-k-1个隔板 取法共有 2^(n-k)种。。
开始找了个规律,话说还真有。。。不过n有10^9次。。。就各种爆。。。这里就只能用显示公式做了
题意:n=1+1+... 或 n=1+2+... 问所有n的等式中,k在右边出现的次数
if(k>n)break
然后就是高中的隔板法。。。 ex. n=8,k=3
1、从8个点中选取3个点 ,则剩下的隔板有 (n-1)-(k+1)=n-k-2个隔板 隔板选法有 2^(n-k-2)种。。。
//看了题解发现这里要再乘一个 (n-k-1) 因为这个等式k这个数只点了一次,相当于点出所有k在此位置的个数
2、取到边界共左右2种,各有 n-k-1个隔板 取法共有 2^(n-k)种。。
#include <stdio.h>
#define ll __int64
#define Mod 1000000007
ll Mul(ll x){
ll ans=1,t=2;
while(x){
if(x&1)ans=(ans*t)%Mod;
t=(t*t)%Mod;
x=x>>1;
}
return ans;
}
int main(){
ll n,k;
int T;scanf("%d",&T);
// printf("%I64d\n",Mul(100000000));
while(T--){
scanf("%I64d %I64d",&n,&k);
if(k>=n-1)
{
if(k==n)printf("1\n");
else if(k==n-1)printf("2\n");//不然会T的
else printf("0\n");
continue;
}
ll ans=Mul(n-k-2);//化简太多 n-k==1就只能先特判掉
ans=ans*(n-k+3);
ans%=Mod;
printf("%I64d\n",ans);
}
return 0;
}