首页 > 其他分享 >ACM暑假训练 中石油oj 3737: 礼物(矩阵快速幂)

ACM暑假训练 中石油oj 3737: 礼物(矩阵快速幂)

时间:2023-06-02 18:36:27浏览次数:53  
标签:Xn oj int 矩阵 ACM zhen 3737 include 礼物



3737: 礼物


时间限制: 5 Sec  内存限制:512 MB

提交: 46  解决: 12

[提交][状态][讨论版]

题目描述


热情好客的小猴请森林中的朋友们吃饭,他的朋友被编号为 1∼N,每个到来的朋友都会带给他一些礼物:香蕉。其中,第一个朋友会带给他1个香蕉,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再加他的编号的K次方那么多个。所以,假设 K=2,前几位朋友带来的礼物个数分别是:
1,5,15,37,83,…
假设 K=3,前几位朋友带来的礼物个数分别是:
1,9,37,111,…
现在,小猴好奇自己到底能收到第 N 个朋友多少礼物,因此拜托于你了。
已知 N,K,请输出第 N 个朋友送的礼物个数 mod 1000000007。


输入


第一行,两个整数 N,K。


输出


一个整数,表示第N个朋友送的礼物个数 mod 1000000007。


样例输入

4 2

样例输出

37

提示


100% 的数据:N≤1018,K≤10。


【解析】:

由题意可以看出:an = S(n-1) + n^k ;

数据量太大,直接递推会超时。

所以用这个递推式,构造矩阵,然后利用矩阵快速幂,从而将时间复杂度从O(n)降到O(log n)

利用二项式分解n^k可得:

(注意注意: Sn = S(n-1) + an)

ACM暑假训练 中石油oj 3737: 礼物(矩阵快速幂)_#include

然后设两个矩阵Xn和Xn+1,令他们:

ACM暑假训练 中石油oj 3737: 礼物(矩阵快速幂)_i++_02

那么一定存在这样的矩阵A。

手算构造这个矩阵A。其中多次用到二项式分解。

特别注意区分Sn和an

构造结果:

ACM暑假训练 中石油oj 3737: 礼物(矩阵快速幂)_矩阵_03

然后,X(n+1) = A * Xn;

则 Xn = A^(n-2) * X2;

A^(n-2)通过矩阵快速幂秒求,然后直接通过X2推出Xn

【代码】:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
struct zhen{
	int r,c;//行列始于1
	ll a[16][16];
	zhen(int R=0,int C=0){
		memset(a,0,sizeof(a));
		r=R;c=C;
	}
};
ll Cf[15][15];//组合数打表
zhen operator*(zhen A,zhen B)//矩阵A*B
{
	zhen C(A.r,B.c);
	for(int i=1;i<=A.r;i++)
		for(int j=1;j<=B.c;j++)
			for(int k=1;k<=A.c;k++){
				C.a[i][j]+=(A.a[i][k]*B.a[k][j])%mod;
				C.a[i][j]%=mod;
			}
	return C;
}
zhen qpow(zhen A,ll m)//方阵A的m次幂
{
	zhen ans(A.r,A.c);
	for(int i=1;i<=A.r;i++) ans.a[i][i]=1;//单位矩阵
	while(m)
	{
		if(m%2)ans=ans*A;
		A=A*A;
		m/=2;
	}
	return ans;
}
ll qpow(ll n,ll m)
{
	n%=mod;
	ll ans=1;
	while(m) 
    {  
        if(m%2)  
            ans=(ans*n)%mod;  
        m/=2;  
        n=(n*n)%mod;
    } 
    return ans;
}
void output(zhen A)
{
	for(int i=1;i<=A.r;i++){
		for(int j=1;j<=A.c-1;j++)
			cout<<A.a[i][j]<<' ';
		cout<<A.a[i][A.c]<<endl;
	}
}
void init()//组合数打表 
{
	Cf[0][0]=1;//特殊
	for(int i=1;i<=13;i++)
		for(int j=0;j<=i;j++)
			Cf[i][j]=(j==0)?1:(Cf[i-1][j]+Cf[i-1][j-1])%mod;
}
int main()
{
	init();//初始化组合数
	ll n,k;
	cin>>n>>k;
	if(n==1){
		puts("1");return 0;
	}
	
	zhen A(k+2,k+2);//构造矩阵A
	A.a[1][1]=2;
	for(int i=2;i<=A.c;i++)//第一二行
		A.a[2][i]=A.a[1][i]=Cf[k][i-2];
	for(int i=3;i<=A.r;i++)//三行往后
		for(int j=i;j<=A.c;j++){
			A.a[i][j]=Cf[A.r-i][j-i];
		}
	//矩阵A构造完毕
	//所以 Xn = A^(n-2) * X2;
	zhen X2(A.r,1),Xn;
	for(int i=1;i<=X2.r;i++)
		X2.a[i][1]=1;
	Xn=qpow(A,n-2)*X2;
	ll ans=Xn.a[1][1]+qpow(n,k);//an = S(n-1) + n^k
	cout<<ans%mod<<endl;
}


矩阵快速幂解决递推题 推荐博文:点击打开链接

要点:将an利用二项式展开,要含有n-1

标签:Xn,oj,int,矩阵,ACM,zhen,3737,include,礼物
From: https://blog.51cto.com/u_16125110/6404533

相关文章

  • 三个博弈-巴什博奕、威佐夫博弈、尼姆博弈。acm博弈算法笔记HDU 2149,1850,1527
    博弈论(一)、acm博弈基础算法BashGame,NimGame和WythoffGame(即巴什博奕、尼姆博弈、威佐夫博弈)Bash  Game: 同余理论Nim   Game: 异或理论WythoffGame: 黄金分割(二)、三个博弈。1、巴什博奕。只有一堆n个物品,两个人轮流从这堆物品中取物, 规定每次至少取一个,......
  • 山东第八届acm大赛F题quadratic equation,山东理工oj 3898
    题目地址:http://www.sdutacm.org/onlinejudge2/index.php/Home/Index/problemdetail/pid/3898.htmlquadraticequationTimeLimit: 2000MS MemoryLimit: 131072KBSubmit Statistic DiscussProblemDescriptionWithgivenintegers a,b,c,youareaskedto......
  • acm杭电2092-整数解
    ProblemDescription有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,它们到底是真还是假,也就是这种整数到底存不存在,实在有点吃不准,你能快速回答吗?看来只能通过编程。例如:x+y=9,x*y=15?找不到这样的整数x和y1+4=5,1*4=4,所以,加起来等于5,乘起......
  • POJO简介【pojo模块】
    DTO(DataTransferObject):数据传输对象,用于接收数据和传输数据,属性和请求参数对应。VO(ViewObject):视图对象,返回给客户端展示用的数据,例如分页对象PageResult{total,List}。PO(PersistantObject):持久化对象,对象属性和数据库表中的字段一一对应,一张表对应一个PO。POJO(PlainOrdi......
  • 使用Hutool的@Alias注解和JSONUtil.toJsonStr()的问题记录
    表格如下: 定义类结构如下:  使用fastjson转换后的结果                                使用hutool的JSONUtil转换之后的结果      可以看到JSONUtil类转换之后格式并不是我们需要的类的字......
  • 2023年6月最新全国省市区县和乡镇街道行政区划矢量边界坐标经纬度地图数据 shp geojso
    发现个可以免费下载全国 geojson 数据的网站,推荐一下。支持全国、省级、市级、区/县级、街道/乡镇级以及各级的联动数据,支持导入矢量地图渲染框架中使用,例如:D3、Echarts等geojson数据下载地址:https://geojson.hxkj.vip该项目github地址:https://github.com/TangSY/echarts-m......
  • Typora Emoji
    title:TyporaEmojicategories:-手册目录PeopleNatureObjectsPlacesSymbolsPeople......
  • Git emoji手册
    title:gitemoji手册tags:-手册-gitcategories:-手册emojiemoji代码commit说明......
  • POJ3608(旋转卡壳--求两凸包的最近点对距离)
    题目:BridgeAcrossIslands  考虑如下的算法,算法的输入是两个分别有m和n个顺时针给定顶点的凸多边形P和Q。1.计算P上y坐标值最小的顶点(称为yminP)和Q上y坐标值最大的顶点(称为ymaxQ)。2.为多边形在yminP和ymaxQ处构造两条切线LP和LQ使得他们对应的多边形位于他们的右侧......
  • POJ1151(线段树+扫描线求矩形面积并)
    题目:http://poj.org/problem?id=1151 #include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>usingnamespacestd;constintN=10005;structnode{intl,r;intcov;doublelen;};structline{......