Partition
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3582 Accepted Submission(s): 1402
Problem Description
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 have
4=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.
Sample Input
2 4 2 5 5
Sample Output
5 1
Source
2013 Multi-University Training Contest 1
Recommend
liuyiding | We have carefully selected several similar problems for you: 6447 6446 6445 6444 6443
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
/*
题目大意:已知n有2^(n-1)种拆分的方法,
那么给定k,计数k在所有拆分方法中出现的次数。
数学题,这道题原本我想烦了。。。
是用数学递推来处理的,但是有太多细节了并且初始情况是F(k,k)=1,
这就更加麻烦了,递推方式的思想也很简单f(n,k)=2^(n-k-1)+sigma i:0~n-1 f(i,k);
这样种方式运行下去,可以得到f(n,k)=2^(n-k-1)+2f(n-1,k);要嵌套一些母函数来处理,最终得到的结果应该是差不多的。
但是不妨用组合计数的方式来思考处理。。。
考虑n个1全铺开,如果k个连续就是当成分解中的k,
那么计数k的方法只要计数这样的连续出现的位置,对于每种位置,
有多少种即可,不会产生重复,因为是以位置来考虑,贡献的思想,每个位置对答案贡献了多少。
分类一下,考虑在中间和在两端的结果,不难得到答案为2^(n-k-2)*(n-k-1)+2^(n-k)
*/
const int maxn =3e3+5;
const int mod=1e9+7;
ll powmod(ll x,ll y){ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
ll n,k;
int main()
{
int t;scanf("%d",&t);
while(t--)
{
scanf("%lld%dlld",&n,&k);
if(k>n) puts("0");
else if(n==k+1) puts("2");
else if(n==k) puts("1");
else
{
ll tp=powmod(2LL,n-k-2)*(n-k-1)%mod+powmod(2LL,n-k);
tp%=mod;
printf("%lld\n",tp);
}
}
return 0;
}