HDU 4602 Partition(快速幂)
2015-07-24 19:14
381 查看
C - Partition
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64d
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≤10 9).
Output
Output the required answer modulo 10 9+7 for each test case, one per line.
Sample Input
Sample Output
题目大意:给出一个数n,按照题目的分解成公式,求数k在所有公式中出现的次数。
找规律
1=1
1:1个
2=1+1
2=2
1:2个
2:1个
3=1+1+1
3=1+2
3=2+1
3=3
1:5个
2:2个
3:1个
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
1:12 个
2;5个
3:2个
4:1个
5=1+1+1+1+1
5=1+1+1+2
5=1+1+2+1
5=1+2+1+1
5=2+1+1+1
5=1+1+3
5=1+3+1
5=3+1+1
5=1+2+2
5=2+1+2
5=2+2+1
5=2+3
5=3+2
5=1+4
5=4+1
5=5
1:28个
2:12个
3:5个
4:2个
5:1个
分析:
当k > n时,结果为0;
当k = n时,结果为1;
当k < n时,把n分成n个1即n=1+1+······+1+1,要想得到一个k即取出k个连续的1组成1个k即可。
设取出来的这k个1的第一位是x,则x的左边有(x-1)个1,根据题意可知,将(x-1)拆分共有2^(x-2)种拆分法,区间[x, x+k-1]所包含的1是取的连续的k个1,它的右边还有[n - (x+k-1)]个1,[n - (x+k-1)]有2^[n - (x+k-1) - 1] = 2^(n-b-k)种拆分法。因此,当取定这个位置的k时,有2^(x-2)
* 2^(n-x-k) = 2^(n-k-2)种情况(注意结果与x无关)。这里没有重复,因为计算每个位置的k只计算他自己一次,而不管其他地方是否也出现了k。
当x = 1时,x的左边没有1,右边有2^(n-b-k) = 2^(n-1-k)种拆分;
当x = n-k+1时,组成的k的右边没有1,左边有2^(b-2) = 2^(n-1-k)种拆分;
当2 <= x <= n-k时,就有(n-k-2+1) * 2^(x-2) * 2^(n-x-k)种拆分;
一共就是2^(n-b-k) + 2^(n-1-k) + (n-k-2+1) * 2^(b-2) * 2^(n-b-k) = (n-k+3)*2^(n-k-2)
注意由于数据比较大,因此用快速幂求解。
AC代码如下:
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64d
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≤10 9).
Output
Output the required answer modulo 10 9+7 for each test case, one per line.
Sample Input
2 4 2 5 5
Sample Output
5 1
题目大意:给出一个数n,按照题目的分解成公式,求数k在所有公式中出现的次数。
找规律
1=1
1:1个
2=1+1
2=2
1:2个
2:1个
3=1+1+1
3=1+2
3=2+1
3=3
1:5个
2:2个
3:1个
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
1:12 个
2;5个
3:2个
4:1个
5=1+1+1+1+1
5=1+1+1+2
5=1+1+2+1
5=1+2+1+1
5=2+1+1+1
5=1+1+3
5=1+3+1
5=3+1+1
5=1+2+2
5=2+1+2
5=2+2+1
5=2+3
5=3+2
5=1+4
5=4+1
5=5
1:28个
2:12个
3:5个
4:2个
5:1个
分析:
当k > n时,结果为0;
当k = n时,结果为1;
当k < n时,把n分成n个1即n=1+1+······+1+1,要想得到一个k即取出k个连续的1组成1个k即可。
设取出来的这k个1的第一位是x,则x的左边有(x-1)个1,根据题意可知,将(x-1)拆分共有2^(x-2)种拆分法,区间[x, x+k-1]所包含的1是取的连续的k个1,它的右边还有[n - (x+k-1)]个1,[n - (x+k-1)]有2^[n - (x+k-1) - 1] = 2^(n-b-k)种拆分法。因此,当取定这个位置的k时,有2^(x-2)
* 2^(n-x-k) = 2^(n-k-2)种情况(注意结果与x无关)。这里没有重复,因为计算每个位置的k只计算他自己一次,而不管其他地方是否也出现了k。
当x = 1时,x的左边没有1,右边有2^(n-b-k) = 2^(n-1-k)种拆分;
当x = n-k+1时,组成的k的右边没有1,左边有2^(b-2) = 2^(n-1-k)种拆分;
当2 <= x <= n-k时,就有(n-k-2+1) * 2^(x-2) * 2^(n-x-k)种拆分;
一共就是2^(n-b-k) + 2^(n-1-k) + (n-k-2+1) * 2^(b-2) * 2^(n-b-k) = (n-k+3)*2^(n-k-2)
注意由于数据比较大,因此用快速幂求解。
// m^n % k int quickpow(int m,int n,int k) { int b = 1; while (n > 0) { if (n & 1) b = (b*m)%k; n = n >> 1 ; m = (m*m)%k; } return b; }
AC代码如下:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug\n" #define pi (acos(-1.0)) #define eps (1e-4) #define inf (1<<28) #define sqr(x) (x) * (x) using namespace std; typedef long long ll; typedef unsigned long long ULL; #define M 1000000007 long long quickpow(long long m,long long n,long long k)//注意数据类型long long型 { int b = 1; while (n > 0) { if (n & 1) b = (b*m)%k; n = n >> 1 ; m = (m*m)%k; } return b; } int main() { long long i,t,n,k; scanf("%d",&t); while(t--) { scanf("%ld%ld",&n,&k); if(k>n) printf("0\n"); else if(n==k) printf("1\n"); else if(k==n-1) printf("2\n"); else printf("%ld\n",(n-k+3)*quickpow(2,n-k-2,M)%M); } return 0; }
相关文章推荐
- Liv555简单移植
- hdu 5308 (2015多校第二场第9题)脑洞模拟题,无语
- 获得一个2n数组中的N个元素,使得该N个元素与剩余元素和最小
- hdu 5308 (2015多校第二场第9题)脑洞模拟题,无语
- PHP生成唯一订单号
- 添加linux启动运行的程序
- [BLE] CC2541的开启广播过程
- appium python 获取手机页面信息
- [leedcode 123] Best Time to Buy and Sell Stock III
- windows下临界区的使用
- new malloc(待更新)
- 使用excel进行数据挖掘(6)---- 预测
- hdu 1348 Wall (凸包模板)
- tmux
- HDU 5301 Buildings
- this指针
- The RGB to YCbCr formula
- Hdu 4612 Warm up (双连通分支+树的直径)
- iOS 类别和扩展(Categories和Extensions)
- GCC参数详解