您的位置:首页 > 其它

多校联合练习赛1 Problem 1003 Partition 排列组合问题

2013-07-25 10:35 399 查看


Partition

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1077    Accepted Submission(s): 439


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

 
感言:
   当时,比赛时。一直没往排列组合问题上考虑。可能被题目跟队友说是DP误导了吧。更多的是自己水平不足吧。 平时做的题目,排列组合做的太少了。没一眼看出来。
直接附上标准题解吧,已经讲的很详细了。
Problem C. Partition

我们可以特判出 n <= k 的情况。

对于 1 <= k < n,我们可以等效为 n 个点排成一列,并取出其中的连续 k 个点。下面分两种

情况考虑:

第一种情况,被选出的不包含端点,那么有(n – k − 1)种情况完成上述操作,剩下未被圈的点

之间还有(n – k − 2)个位置,可以在每个位置断开,所以共 2^(n−k−2) ∗ (n−k−1)种方法。

第二种情况,即被选出的包含端点,那么有 2 种情况,并且剩余共(n – k − 1)个位置,所以共

2 ∗ 2^(n – k − 1)种方法。

总计 2 ∗ 2^(n – k − 1) + 2^(n – k − 2) ∗ (n – k − 1) = (n – k + 3) * 2^(n – k − 2)。

就是最后要用下快速幂算法。
/*
* @author ipqhjjybj
* @date  20130725
*
*/

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

#include <iostream>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <utility>

#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
using namespace std;

#define inf 0x3f3f3f3f
#define MAXN 100005
#define clr(x,k) memset((x),(k),sizeof(x))
#define clrn(x,k) memset((x),(k),(n+1)*sizeof(int))
#define cpy(x,k) memcpy((x),(k),sizeof(x))
#define Base 10000

typedef vector<int> vi;
typedef stack<int> si;
typedef vector<string> vs;
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define rep(i,n) for(int i = 0;i < n;++i)
#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)

#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

#define ll long long
const int MOD=1e9+7;
ll quick_mod(ll base,ll n){
ll ret=1;
while(n){
if(n&1)
ret=ret*base%MOD;
base=base*base%MOD;
n>>=1;
}
return ret;
}
int main(){
int t;
int n,k;
ll ans;
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&k);
if(k>n) ans=0;
else if(k==n) ans=1;
else if(k==n-1) ans=2;
else ans=(long long)(n-k+3)*quick_mod(2,n-k-2)%MOD;
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息