首页 > 其他分享 >Luogu P4139 上帝与集合的正确用法

Luogu P4139 上帝与集合的正确用法

时间:2022-09-18 16:12:11浏览次数:92  
标签:int Luogu bmod varphi 用法 P4139 pmod 定理 欧拉

\(\large{题目链接}\)
\(\\\)
首先介绍一下欧拉定理:

\[a^{\varphi(p)}\equiv 1\pmod{p}, \gcd(a,p)=1 \]

\(\\\)
所以费马小定理其实是欧拉定理的一种特殊情况,即\(p\)为质数时,\(\varphi(p)=p-1\)
\(\\\)
在算法竞赛中我们经常会用到欧拉定理的一个推论:

\[a^{b}\equiv a^{b \mod \varphi(m)}, \pmod{m},\ \gcd(a,m)=1 \]

因为\(a^{b}=a^{\varphi(m) \times \lfloor\frac{b}{\varphi(m)}\ \ \rfloor + b \bmod \varphi(m)}=a^{b \bmod \varphi(m)}\),有了这个推论,即使\(b\)比较大,我们可以依照\(a^{b \bmod \varphi(m)}\)来轻松计算,不过需要\(a\)和\(m\)互质。
\(\\\)
那么如果\(\ \gcd(a,p)\ne 1\)呢,那么我们就要用到扩展欧拉定理(EX)。
\(\\\)
扩展欧拉定理:
若\(b \geqslant \varphi(m)\),\(a^{b}\equiv a^{b\bmod \varphi(m) + \varphi(m)}, \pmod{m},b \geqslant \varphi(m)\),若\(b \leqslant \varphi(m),a^{b} \equiv a^{b \bmod \varphi(m)},\pmod{m}\)。
\(\\\)
讲完前置知识,那我们回到这个题,求\(2^{2^{2^{2^{...}}}}\pmod{p}\),显然\(2^{2^{2^{2^{...}}}}\)是一个很大的数,我们想到用欧拉定理,又题目中没有说明\(p\in prime\),所以我们想到用扩展欧拉定理,只需考虑\(b \geqslant \varphi(p)\)即可。
\(\\\)
\(2^{2^{2^{2^{...}}}} \equiv 2^{2^{2^{2^{...}}} \bmod \varphi(p) + \varphi(p)},\pmod{p}\),这是一个递归过程,我们考虑边界,一定会有\(\varphi(1)=1\)时,此时返回\(2^{x \bmod 1 + 1} = 2 ^ {1}=2\)
\(\\\)

#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
const int N = 1e7 + 5;
int t, p, cnt, vis[N], phi[N], pri[N];

int read() {
	int x = 0, f = 1;
	char c = getchar();
	while (!isdigit(c)) {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
	return x * f;
}

inline void varphi() {
	phi[1] = 1;
	for (int i = 2; i <= N; ++i) {
		if (!vis[i]) pri[++cnt] = i, phi[i] = i - 1;
		for (int j = 1; j <= cnt && pri[j] * i <= N; ++j) {
			vis[i * pri[j]] = 1;
			if (i % pri[j] != 0) phi[i * pri[j]] = phi[i] * (pri[j] - 1);
			else {
				phi[i * pri[j]] = phi[i] * pri[j];
				break;
			}
		}
	}
}

inline ull quick_pow(int x, int y, int Mod) {
	ull ans = 1, base = x % Mod;
	while (y) {
		if (y & 1) ans = (ans * base) % Mod; 
		base = (base * base) % Mod;
		y >>= 1;
	}
	return ans;
}

inline int solve(int Mod) {
	//cout << "1";
	if (Mod == 1) return 2;
	return quick_pow(2, solve(phi[Mod]) + phi[Mod], Mod);
}

int main() {
	varphi();
	t = read();
	while (t--) {
		p = read();
		printf("%d\n", solve(p));
	}
	return 0;
}

标签:int,Luogu,bmod,varphi,用法,P4139,pmod,定理,欧拉
From: https://www.cnblogs.com/Miraclys/p/16704013.html

相关文章

  • this.$set用法
    原文地址:https://www.cnblogs.com/birdy-silhouette/p/14793709.htmlthis.$set()的主要功能是解决改变数据时未驱动视图的改变的问题,也就是实际数据被改变了,但我们看到的......
  • Luogu P3674 小清新人渣的本愿 题解
    P3674小清新人渣的本愿lxl大爷的题,%%%%%以及CSPrp++!!!前言:其实是这题的名字吸引了我,毕竟人渣的本愿里的角色我觉得多多少少都沾点,哪来的小清新啊。《人渣的本愿》,又名......
  • Toolbar工具条控件style样式使用感受和用法分享
    Toolbar工具条不知道能不能代替plus做成大按钮样式.....它的style样式有好多种,下面记录下自己使用过程常规样式importwin.ui;importwin.ui.toolbar;/*DSG{{*/va......
  • SQL Server中Merge子句、CTE、CONCAT、FORMAT函数用法
    Merge子句把源数据合并到目标表点击查看代码CREATETABLEa(keycolINTPRIMARYKEY,col1INTNOTNULL,col2INTNOTNULL,col3INTNOTNULL);CREATE......
  • 16.1json模块 16.2文件上传 16.3session的高级用法
    16.1json模块#json主要是干嘛的?json非常严格的数据类型,只能用“”,不然会报错,只支持""#把一个东西变成序列#[1,2,3,4,5]#有序的叫序列#{"a",'b'}#散列#importjson......
  • mysql中find_in_set()函数的使用及in()用法详解
    这篇文章主要介绍了mysql中find_in_set()函数的使用以及in()用法详解,需要的朋友可以参考下 MySQL手册中find_in_set函数的语法解释:FIND_IN_SET(str,strlist)str要......
  • 【Python】math 模块用法
    math模块一些用法trunc(x)传入整数或浮点数,返回数值的整数部分,忽略小数部分,不会四舍五入importmathmath.trunc(2.77)#2math.trunc(8.32)#8math.trunc......
  • QT之QCompleter的用法--- 最简单的使用方法
    本文讲解最简单的使用方法:QCompleter能实现自动填充功能,方便用户输入,提升用户的体验,一般和QLineEdit与QComboBox搭配起来使用.先来个最简单的示例:QStringListword_l......
  • Python 取整函数汇总- round()、int()、floor()、ceil()的用法
    对每位程序员来说,在编程过程中数据处理是不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理。取整的方式则包括向下取整、四舍五入、向......
  • NamedTuple技巧用法
    PS:第一眼看到这个代码的时候,就联想到了go中的构造函数,虽然知道go中的构造函数其实就类比于python中的构造函数__init__,但是不得不说,这个太像了在日常编码中,我们经常需要......