Partition
題目串連:Click here~~~~
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
題目解析:
正如題中所說,每次都要把所有的等式寫出來,然後在數出每個數字出現的次數,這就提示我們每個數字出現的次數必然是有關係的,或者可以這樣說,是有公式或規律的。下面大家可以看一下6以內每個數字出現次數:
1:64 a6
2:28 1:28 a5
3:12 2:12 1:12 a4
4: 5 3: 5 2: 5 1: 5 a3
5: 2 4: 2 3: 2 2: 2 1: 2 a2
6: 1 5: 1 4: 1 3: 1 2: 1 1: 1 a1
不難發現,從第三項開始滿足 a3 = 2*a2+2^0,a4 = 2*a3+2^1,a5 = 2*a4+2^2,a6 = 2*a5+2^3,那麼將其全部轉化為有關 a2 的等式,然後將 a2 = 2 代入,那麼為
a3 = 2 ^ 2 + 2^0,
a4 = 2 ^ 3 + 2 * 2^1,
a5 = 2 ^ 4 + 3 * 2^2,
a6 = 2 ^ 5 + 4 * 2^3,
*******
an = 2 ^ ( n-1 ) + ( n-2 ) * 2 ^ ( n-3 ) =( n+2 ) *2 ^ ( n-3 ) ;
又發現,求 n 中的第 k 個數字,相當於求 a ( n-k+1) 的值,則將式中的 n 換為 n-k+1 即可。即公式為( n-k+3 ) * 2 ^ ( n-k-2 ) ;另外,還要考慮 n<k 的情況,且還要用到二分冪。具體代碼如下:
#include<stdio.h>__int64 M = 1e9 + 7 ;__int64 fun1(__int64 b){ __int64 x, sum; if(b == 1 || b == 0) return 2; x = fun1 (b / 2); sum = (x%M) * (x%M) % M; if(b%2) sum = sum * 2 % M; return sum;}int main(){ __int64 N; __int64 m,n,a,b; scanf("%I64d",&N); while(N--) { scanf("%I64d%I64d",&m,&n); if(m<n) {printf("0\n");continue;} if(m==n) {printf("1\n");continue;} if(m-n==1) {printf("2\n");continue;} if(m-n==2) {printf("5\n");continue;} a = fun1( m - n - 2); b = (m - n + 3) * a % M; printf("%I64d\n",b); }}