当前位置: 首页 > news >正文

可做题2(矩阵快速幂,乘法逆元,exgcd)

题目链接:可做题2 (nowcoder.com)

题目描述

若一个数列a满足条件an=an-1+an-2,n ≥ 3,而a1,a2为任意实数,则我们称这个数列为广义斐波那契数列。
现在请你求出满足条件a1=i,a2为区间[l,r]中的整数,且ak mod p=m的广义斐波那契数列有多少个。
 

输入描述:

本题包含多组数据,输入第一行包含一个正整数T,表示数据组数。对于每组数据:
一行六个用空格隔开的整数i,l,r,k,p,m,意义如题目描述所示。

输出描述:

输出共T行,每行一个数表示该组数据的答案。

示例1

输入

复制6 2 17 68 3 23 1 1 17 68 3 57 1 5 17 68 10 11 9 5 17 68 10 71 9 10 17 68 11 12 3 10 17 68 8 6 4

6
2 17 68 3 23 1
1 17 68 3 57 1
5 17 68 10 11 9
5 17 68 10 71 9
10 17 68 11 12 3
10 17 68 8 6 4

输出

复制3 1 4 1 5 9

3
1
4
1
5
9

备注:

对于所有数据,0 ≤ l ≤ r,1 ≤ p ≤ 109,0 ≤ m < p,T=10,0 ≤ i ≤ 1018,k ≥ 3。

思路:对于这个题一看斐波那契,数据又很大,应该立马就想到了矩阵快速幂,再接着看akmodp=m,可能又跟扩展欧几里得有关系,由于p可能不是质数,所以需要判断不互质的情况,然后使用扩展欧几里得或欧拉定理求解同余方程。

首先可以发现 ak=f(k-2)+f(k-1)*x;首先利用矩阵快速幂求出ak。可以利用矩阵a[2][2]={1,1,1,0}这样的一个矩阵,然后k次方就行 了,也就是a[2][2]*(a[2][2]^(k-1)),然后算出ak,我们得到f[1][1]和f[2][1],即f(k-1)和f(k-2),然后exgcd解方程 , 每隔p/gcd 个就有一个解

如果l-x>1的话,结果就是:

(r-x)/(p/gcd)+1-(l-x-1)/(p/gcd)+1;

更详细题解:可做题2(Code+12月网络赛)(扩欧+矩阵快速幂)_Coco_T_的博客-CSDN博客

#include<bits/stdc++.h>
#define lmw ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
//int n,m;
const int N=105;
int f[N][N],a[N][N];
// const int mod=1e9+7;
int c[N][N];
int i,l,r,k,pp,m,x,y;
int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	int gcd=exgcd(b,a%b,x,y);
	int z=x;
	x=y;
	y=z-(a/b)*y;
	return gcd;
}
void mul(int c[],int a[],int b[][N]){
	int s[N]={0};
	for(int i=0;i<=2;i++){
		for(int j=0;j<=2;j++){
			s[i]=(s[i]+a[j]*b[j][i])%pp;
		}
	}
	memcpy(c,s,sizeof(s));
}
void mul(int c[N][N],int a[N][N]){
	int p[N][N]={0};    
	for(int i=1;i<=2;i++){
		for(int j=1;j<=2;j++){
			for(int k=1;k<=2;k++){
			p[i][j]=(p[i][j]+c[i][k]*a[k][j])%pp;				
			}
		}
	}
	memcpy(a,p,sizeof(p));
}
int cal(int x,int y){
	if(x<y) return 0;
	return (x-y)/pp+1;
}
int solve(int xx,int yy){
	int c=__gcd(xx,pp);
	if(yy%c!=0) return 0;
	xx/=c;
	yy/=c;
	pp/=c;
//	int xx,yy;
	int res=exgcd(xx,pp,x,y);
    x=(x*yy+pp)%pp;
	x=(pp+x%pp)%pp;
	return (int)(cal(r,x)-cal(l-1,x)); 
}
signed main(){
    lmw;
	int t;
	cin>>t;
	while(t--){
        a[1][1]=1,a[1][2]=1;
	    a[2][1]=1,a[2][2]=0;
		cin>>i>>l>>r>>k>>pp>>m;
		i%=pp;
		k-=3;
		f[1][1]=1,f[1][2]=1;
        f[2][1]=1,f[2][2]=0;
		while(k){
			if(k&1) mul(a,f);
			mul(a,a);
			k/=2;
		}
		int ans=f[1][1]%pp;
		int sum=((m-f[2][1]%pp*i%pp)%pp+pp)%pp;
//         cout<<ans<<" "<<sum<<" ";
		cout<<solve(ans,sum)<<"\n";
	}
}

AC代码:

相关文章:

  • Mysql用户权限分配详解
  • 一文7个步骤从0到1教你搭建Selenium 自动化测试环境
  • 【网络安全工程师】从零基础到进阶,看这一篇就够了
  • 【C陷阱与缺陷】----语法陷阱
  • 解忧杂货铺(五续集):用了无法离开的网站资源
  • 功能测试转型测试开发年薪27W,又一名功能测试摆脱点点点,进了大厂
  • iOS 紧急通知
  • 艹,终于在8226上把灯点亮了
  • Linux上用Samba建立共享文件夹并通过Linux测试
  • shell简单使用介绍
  • 关于中级开发工程师常问的面试题
  • 蓝桥杯刷题第二十天
  • 二叉树(数据结构系列9)
  • mybatis-plus的批量新增insertBatchSomeColumn
  • Linux内核IO基础知识与概念
  • Android 控件背景颜色处理
  • Centos6.8 使用rpm安装mysql5.7
  • JavaScript函数式编程(一)
  • Nacos系列:Nacos的Java SDK使用
  • ng6--错误信息小结(持续更新)
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • WePY 在小程序性能调优上做出的探究
  • 复杂数据处理
  • 给Prometheus造假数据的方法
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 利用DataURL技术在网页上显示图片
  • 深入浏览器事件循环的本质
  • 世界上最简单的无等待算法(getAndIncrement)
  • 阿里云移动端播放器高级功能介绍
  • ​第20课 在Android Native开发中加入新的C++类
  • # include “ “ 和 # include < >两者的区别
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #DBA杂记1
  • #FPGA(基础知识)
  • #HarmonyOS:基础语法
  • #pragma once
  • (07)Hive——窗口函数详解
  • (SpringBoot)第七章:SpringBoot日志文件
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (篇九)MySQL常用内置函数
  • (十八)SpringBoot之发送QQ邮件
  • (四)c52学习之旅-流水LED灯
  • (译) 函数式 JS #1:简介
  • (转)EOS中账户、钱包和密钥的关系
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .Net各种迷惑命名解释
  • /proc/vmstat 详解
  • :中兴通讯为何成功
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [C++基础]-初识模板