2 4 2 5 5
5 1
对于1 <= k < n,我们能够等效为n个点排成一列,并取出当中的连续k个,这连续的看K个两端断开;
1、若取得是这K个点包含端点(我们仅仅考虑一个端点的情况),还剩下(n-k-1)个间隔,
每一个间隔有断开和闭合两种状态,故有2^(n-k-1),最后乘以2;
2、若取得是这K个点不包含端点,这连续的K个点有(n-k-1)种取法,还剩下(n-k-2)个间隔,
故有2^(n-k-2)*(n-k-1);
总计2 ? 2^(n – k ? 1) + 2^(n – k ? 2) ? (n – k ? 1) = (n – k + 3) * 2^(n – k ? 2)。
#include"stdio.h" #include"string.h" #include"queue" #include"vector" #include"algorithm" using namespace std; #define LL __int64 const int mod=1000000007; int main() { int T,i,n,k; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); if(n<k) printf("0\n"); else if(n==k) printf("1\n"); else { LL d=n-k,s1,t; if(d==1) printf("2\n"); else { s1=d+3; d-=2; LL aa=2,tmp=1; while(d) { if(d&1) tmp*=aa; d/=2; aa=(aa*aa)%mod; tmp%=mod; } printf("%I64d\n",(tmp*s1)%mod); } } } return 0; }
原文:http://www.cnblogs.com/bhlsheji/p/4065832.html