Partition
Define f(n) as the number of ways to perform n in format of the sum of some positive integers. For instance, when n=4, we have4=1+1+1+1
4=1+1+2
4=1+2+1
4=2+1+1
4=1+3
4=2+2
4=3+1
4=4
totally 8 ways. Actually, we will have f(n)=2(n-1) after observations.
Given a pair of integers n and k, your task is to figure out how many times that the integer k occurs in such 2(n-1) ways. In the example above, number 1 occurs for 12 times, while number 4 only occurs once.
input:The first line contains a single integer T(1≤T≤10000), indicating the number of test cases.
Each test case contains two integers n and k(1≤n,k≤109).
output:Output the required answer modulo 109+7 for each test case, one per line.
这道题很容易找到规律,首先若我们要求 num(n,k),我们可以得到num(n,k)==num(n-1,k-1),进一步得到num(n,k)==num(n-k+1,1),
对于num(n,1),也可以找到规律,这个稍微麻烦点,首先我们可以求出对于给定的n,它的展开式中1到n一共出现了多少次,这个值等于 :
C(n-1,0)*n+C(n-1,1)*(n-1)+C(n-2,2),*(n-2)+.......+C(n-1,n-1)*1==2^(n-2)*(n+1)
(这里的C指的是组合数,^符号表示乘方).
则num(n,1)=2^(n-2)*(n+1)-2^(n-3)*(n)=2^(n-3)*(n+2),
所以对于任何n,k,我们都可以求的答案,注意对于n<3时,要特殊判定,这个很好求吧。。。。以下是代码:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#define ll long long
#define mod 1000000007
using namespace std;
int a[3][3];
ll abmodn(ll a,ll b,ll n)
{
ll d=1,i,bi[40],num=0;
while(b>0)
{
bi[num++]=b%2;
b/=2;
}
for(i=num-1;i>=0;i--)
{
d=(d*d)%n;
if(bi[i])
d=(a*d)%n;
}
return d;
}
int main()
{
//freopen("dd.txt","r",stdin);
a[1][1]=a[2][2]=1;
a[2][1]=2;
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
int n,k;
scanf("%d%d",&n,&k);
n=n-k+1;
k=1;
if(n<3)
printf("%d\n",a[n][k]);
else
{
ll ans=((n+2)*abmodn(2,n-3,mod))%mod;
cout<<ans<<endl;
}
}
return 0;
}