CSUOJ 2021: Exponial

2021: Exponial

Description

在这里插入图片描述

在这里插入图片描述

Input

There will be several test cases. For the each case, the input consists of two integers n (1 ≤ n ≤ 1e9) and m (1 ≤ m ≤ 1e9).

Output

Output a single integer, the value of exponial(n) mod m.

Sample Input

2 42
5 123456789
94 265

Sample Output

12
16317634
39

Hint

因为听群里面的dalao们在讨论oj查重问题时说这道题就是一个纯板子题,于是兴冲冲地想来做一下。主要用到了两个模板和一个公式:欧拉函数模板和幂取模模板,指数循环定理。

//欧拉函数模板
long long int oula(long long int n)
{
   long long int res = n, a = n;
   for (long long int i = 2; i*i <= a; ++i)
   {
   	if (a%i == 0)
   	{
   		res = res / i * (i - 1);
   		while (a%i == 0) a = a / i;
   	}
   }
   if (a > 1)res = res / a * (a - 1);
   return res;
}
//幂取模模板(1)
long long int pow_mod(long long int a, long long int n, long long int m)
{
   if (n == 0) return 1;
   long long int x = pow_mod(a, n / 2, m);
   long long int ans = x * x%m;
   if (n % 2 == 1) ans = ans * a%m;
   return ans;
}
//幂取模模板(2)
long long int pow_mod(int x, int p, long long int mod) 
{
   long long int rec = 1;
   while (p > 0)
   {
   	if (p & 1) rec = (long long int)rec * x % mod;
   	x = (long long int)x * x % mod;
   	p >>= 1;
   }
   return rec;
}

在这里插入图片描述
然而,就算已经知道了这些,菜鸡如我还是在各种出错。说起来我还是第一次遇到爆内存的情况,有些手足无措,以为是因为全都无脑开了long long int的原因,然而改了以后就开始WA了,我试图去分析哪些地方可以用int,哪些地方不用long long int就会爆,然而好像分析错误。。。其实到最后不得不承认我的心态已经崩了,开始各种无脑提交,随便改了一点点就开始交,然后再错,再崩,这种情况一定要引起重视,心态还是要磨砺。最后发现好像是自己忽略了指数循环定理的使用条件,以为递归到1或2总是可以解决问题的,然而并非如此。
在这里插入图片描述
小于等于4的情况还是要特殊处理一下的。
总结下来就是一定要真正去理解模板,注意定理的使用条件,还有就是心态要好,最后就是不要凌晨的时候做题…
在这里插入图片描述

#include<stdio.h>
int n, m;
long long int oula(long long int n)
{
	long long int res = n, a = n;
	for (long long int i = 2; i*i <= a; ++i)
	{
		if (a%i == 0)
		{
			res = res / i * (i - 1);
			while (a%i == 0) a = a / i;
		}
	}
	if (a > 1)res = res / a * (a - 1);
	return res;
}
/*long long int pow_mod(long long int a, long long int n, long long int m)
{
	if (n == 0) return 1;
	long long int x = pow_mod(a, n / 2, m);
	long long int ans = x * x%m;
	if (n % 2 == 1) ans = ans * a%m;
	return ans;
}*/
long long int pow_mod(int x, int p, long long int mod) 
{
	long long int rec = 1;
	while (p > 0)
	{
		if (p & 1) rec = (long long int)rec * x % mod;
		x = (long long int)x * x % mod;
		p = p / 2;
	}
	return rec;
}
long long int calculate(long long int n, long long int m)
{
	if (m == 1)
		return 0;
	else if (n == 1)
		return 1;
	else if (n == 2)
		return 2 % m;
	else if (n == 3)
		return 9 % m;
	else if (n == 4) 
		return pow_mod(4, 9, m);
	else
	{
		long long int phim = oula(m);
		return pow_mod(n, calculate(n - 1, phim) + phim, m);
	}
}
int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		printf("%lld\n", calculate(n, m));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值