2013 多校联合 C Partition (hdu 4602)

来源:互联网 发布:编程珠玑下载 编辑:程序博客网 时间:2024/05/16 02:21


http://acm.hdu.edu.cn/showproblem.php?pid=4602

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 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.


这道题很容易找到规律,首先若我们要求 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 1000000007using 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;}