2013 多校联合 C Partition (hdu 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 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值