蓝桥杯 算法训练 数的潜能

本文解析了如何通过快速幂算法解决蓝桥杯算法问题,涉及将大数N分解为多个正整数之和的潜能M,并求取M对5218的余数。关键步骤包括对1到4的特殊处理和利用快速幂技巧计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蓝桥杯 算法训练 数的潜能

题目描述

  • 资源限制
    时间限制:1.0s 内存限制:256.0MB
  • 问题描述
    将一个数N分为多个正整数之和,即N=a1+a2+a3+…+ak,定义M=a1*a2*a3*…*ak为N的潜能。
    给定N,求它的潜能M。
    由于M可能过大,只需求M对5218取模的余数。
  • 输入格式
    输入共一行,为一个正整数N。
  • 输出格式
    输出共一行,为N的潜能M对5218取模的余数。
  • 样例输入
    10
  • 样例输出
    36
  • 数据规模和约定
    1<=N<10^18

思路

	(1) n = 1  ,   ans=1;
	(2) n > 1  ,   假设 n = a1 + a2;  且 a1<=a2 
		1. a1=1 且 a2=1,  则 ans=1 
		2. 设a1=1, a2>1,  则 设a2=c+d
			  若存在c,d 使 a2=c+d<=c*d,  说明a2可以再分, 此时有a2>=4 
			  反之若对所有c,d 使 a2=c+d>c*d,  说明a2不可以再分, 此时只有a2=2,3 
		3. 设1<a1<=a2<4 , 则  由以上分析可得 a1, a2 不可再分
		4. 若a1>=4或a2>=4, 则 可以继续分解, 分解为一系列2和3的和
			当 2的个数大于3个时, 3个2可以转化为2个3, 而且也必须转化为两个3, 因为3*3>2*2*2
			即一系列数中至多只有两个2 
	综上所述:当n=[1 2 3]时, ans=[1 1 2] 
			  当n>4时, n分解为至多2个2和一系列的3 

方案1 快速幂+取余

  • 易错点:pow(a, b)的返回值是double, 需要四舍五入转成int 即int(pow(a, b)+0.5) , 直接int()转可能会出错
#include<iostream>
#include<cmath>

using namespace std;

long long int n;		//正整数n 
int ans; 

//函数功能:快速幂取余  返回(a^b)%p 
//主要思想:设b=c0*2^0 + c1*2^1 + ... + ck*2^k ; 
//			则a^b = a^(c0*(2^0)) * a^(c1*(2^1)) * ... * a^(ck*(2^k))  
//			故a^b%p = ( (a^(c0*(2^0)))%p * (a^(c1*(2^1)))%p * ... * (a^(ck*(2^k)) ) %p
//			且 (a^(2^k))%p = ((a^(2^(k-1))) %p)^2  %p
int f(int a, long long int b, int p){
	int ans=1;
	int i=0;
	int temp=a%p;      //temp =  a^(c0*(2^0)) %p
	ans = (ans * int(pow(temp, b&1)+0.5) ) %p;  //ans = (a^(c0*(2^0)))%p
	b >>= 1;
	
	while(b>0){
		temp = (temp*temp) %p;    
		ans = (ans * int(pow(temp, b&1)+0.5)) %p;
		b >>= 1;	
	}
	return ans;	
} 

int main(){	
	cin>>n;
	if(n<3){
		cout<<n<<endl;
	}else{
		// (3-(n%3))%3)  :  2的个数 
		cout<< (1<<((3-(n%3))%3)) * f(3, (n-2*((3-(n%3))%3))/3, 5218) %5218<<endl;
	}
	return 0; 
} 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值