HDU 4602 Partition (矩阵快速幂或求通项)
来源:互联网 发布:美津浓2016跑鞋矩阵 编辑:程序博客网 时间:2024/05/21 10:23
Partition
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3462 Accepted Submission(s): 1348
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
题意
对于一个数n可以拆成题意所给的形式,给你n和k问你k在n所拆成的形式中出现了几次
思路
我们先写一写1 2 3 4 5中各项的值
1 1
2 1 2
3 1 2 5
4 1 2 5 12
5 1 2 5 12 28
写到5我们其实就可以发现值的出现是具有一定规律的,5中有1个5,2个4,5个3,12个2,28个1
然后我们再观察一下这些数会很容易发现:
2=2*1+0
5=2*2+1
12=2*5+2
28=2*12+4(多写一步6中有几个1,会发现是64个)
64=2*28+8
也就是说这些式子从2开始满足:
原题的n和k可以化成n=n-k
对于
所构造的矩阵如下
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 3using namespace std;typedef struct{ long long m[MAX][MAX];} Matrix;Matrix P= {2,0,2,0,2,1,0,0,2};Matrix I= {1,0,0,0,1,0,0,0,1};const long long mod=1e9+7;Matrix Matrixmul(Matrix a,Matrix b){ int i,j,k; Matrix c; for(i=0; i<MAX; i++) for(j=0; j<MAX; j++) { c.m[i][j]=0; for(k=0; k<MAX; k++) { c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod; } c.m[i][j]%=mod; } return c;}Matrix quickpow(long long n){ Matrix m=P,b=I; while(n>0) { if(n%2==1) b=Matrixmul(b,m); n=n/2; m=Matrixmul(m,m); } return b;}int main(){ int t; scanf("%d",&t); while(t--) { int n,k; scanf("%d%d",&n,&k); int m=n-k; if(m<0) { printf("0\n"); } else if(m==0) { printf("1\n"); } else if(m==1) { printf("2\n"); } else if(m==2) { printf("5\n"); } else { Matrix A=quickpow(m-2); printf("%lld\n",(A.m[0][0]*5+A.m[0][1]*2+A.m[0][2]*1)%mod); } } return 0;}
然后说说怎么求解通项
线性非齐次递推关系
由an−2an−1=2n−2 可得到特征方程x2−2x=0 ,解得x=2,x=0
特征根为一重根
所以特解∗an=kn2n−2 ,代入原式得k=1
那么有an=(An+B)2n+n2n−2 ,再代入a2=5,a3=12
得A=0,B=34
那么有an=(3+n)2n−2 ,,n≥2 构造等差数列
an−2an=2n−2 两边同时除以2n 有
an2n−an−12n−1=14
所以有an2n=54+(n−2)14
那么an=542n+(n−2)142n
即an=(3+n)2n−2 ,,n≥2
#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string.h>using namespace std;const long long mod=1e9+7;long long quickmod(long long n){ long long ans=1; long long a=2; while(n>0) { if(n%2==1) ans=(ans*a)%mod; a=a*a%mod; n/=2; } return ans;}int main(){ int t; scanf("%d",&t); while(t--) { long long n,k; scanf("%lld%lld",&n,&k); if(n-k<0) printf("0\n"); else if(n-k==0) printf("1\n"); else if(n-k==1) printf("2\n"); else { n=n-k; printf("%lld\n",(n+3)*quickmod(n-2)%mod); } } return 0;}
- HDU 4602 Partition (矩阵快速幂或求通项)
- hdu-4602-Partition(矩阵快速幂)
- hdu - 4602 - Partition(快速幂)
- HDU 4602 Partition 数论 AND 快速幂
- HDU 4602 Partition(快速幂)
- HDU 4602 Partition (快速幂+思维)
- HDU-1005 Number Sequence(矩阵快速幂或模拟)
- HDU 6050 Funny Function(矩阵快速幂或公式)
- hdu 4602 Partition (递推+二分快速幂)
- HDU 4990 Reading comprehension(递推+快速幂 或 矩阵快速幂)
- 快速幂或矩阵快速幂
- 【矩阵快速幂】hdu 1575
- 【矩阵快速幂】hdu 1757
- hdu 2604 矩阵快速幂
- hdu-1575矩阵快速幂
- hdu 1575 矩阵快速幂
- hdu 1575(矩阵快速幂)
- hdu 3306 矩阵快速幂
- Spring整合Quartz实现定时任务调度
- 逐图元的反走样
- 如何优雅的抄袭代码?天下代码一大抄,这才是正确的姿势
- 语言实践2-驱动学习(1)hello world驱动
- 伪装撒谎和识别敌我是否应加入,2018新版世界AI智商评测标准探讨
- HDU 4602 Partition (矩阵快速幂或求通项)
- 公有云托管K8s服务百花齐放,企业如何统一纳管、便捷管理?
- 经典算法之冒泡排序
- Linux C之IO操作
- Markdown的基本使用
- windows环境将Python脚本做成系统服务
- python高级3:其他知识点2
- 图片数据集太少?Keras Image Data Augmentation 各参数详解
- 「无中生有」计算机视觉探奇