【初等数论】个人数论总结


ε=(´ο`*)))唉,又快学完初等数论了,我又心血来潮,再次写下一篇壮美的篇章。

一 夜 复 习 两 茫 茫 。 看 一 句 , 忘 三 行 。 路 遇 友 人 , 脸 色 皆 凄 凉 。 视 死 如 归 入 考 场 , 做 小 抄 , 占 座 忙 。 考 完 之 后 心 凉 凉 , 左 右 曰 , 今 必 亡 。 查 询 成 绩 , 众 人 皆 过 我 独 亡 。 再 顾 昔 时 左 右 人 , 这 一 群 , 装 逼 郎 。 — — — 题 记 一夜复习两茫茫。\\看一句,忘三行。\\路遇友人,脸色皆凄凉。\\视死如归入考场,做小抄,占座忙。\\ 考完之后心凉凉,左右曰,今必亡。\\查询成绩,众人皆过我独亡。\\再顾昔时左右人,这一群,装逼郎。\\———题记 ,,


进制

略带而过

十进制转二进制

(1)短除法

在这里插入图片描述

(2)贪心算法

在这里插入图片描述

二进制转十进制

N ( 十 进 制 ) = a n ∗ 2 n + a n − 1 ∗ 2 n − 1 + … … + a 1 ∗ 2 1 + a 0 ∗ 2 0 N(十进制)=a_n*2^n+a_{n-1}*2^{n-1}+……+a_1*2^1+a_0*2^0 N()=an2n+an12n1++a121+a020

b进制转十进制

乘以基数并展开:
x = a n ∗ b n + a n − 1 ∗ b n − 1 + … … + a 1 ∗ b 1 + a 0 ∗ b 0 x=a_n*b^n+a_{n-1}*b^{n-1}+……+a_1*b^1+a_0*b^0 x=anbn+an1bn1++a1b1+a0b0
x = ( … ( a n ∗ b + a n − 1 ) ∗ b + … ) ∗ b + a 0 x=(…(a_n*b+a_{n-1})*b+…)*b+a_0 x=((anb+an1)b+)b+a0

十进制转b进制

在这里插入图片描述

快速幂

快速幂,顾名思义,就是快速计算某个数的多少次幂,其时间复杂度为 Θ ( log ⁡ 2 x ) \Theta(\log_2 x) Θ(log2x)

预备知识
在这里插入图片描述
原理倍增思想
a ∗ a = a 2 a 2 2 = a 4 a 4 2 = a 8 a*a=a^2\\{a^2}^2=a^4\\{a^4}^2=a^8 aa=a2a22=a4a42=a8

【核心代码】

int pow(int a,int b,int p)//快速幂求a^b%p 
{
	int res=1;
	for(;b;b>>=1)
	{
		if(b&1) res=(ll)res*a%p;
		a=(ll)a*a%p; 
	}
	return res;
} 

例题1:越狱

【题目描述】
监狱有连续编号为 1.. n 1..n 1..n n n n个房间,每个房间关押一个犯人。有 m m m种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱,结果模 100003 100003 100003取余。 1 ≤ m ≤ 1 0 8 , 1 ≤ n ≤ 1 0 12 。 1≤m≤10^8,1≤n≤10^{12}。 1m1081n1012
【解析】
发生越狱的情况下不太好分析,所以我们可以先算出总方案数再减去不发生越狱的情况。
显然,所有的方案数为 m n m^n mn ,所有不发生越狱的方案数为 m ∗ ( m − 1 ) ( n − 1 ) m*(m-1)^{(n-1)} m(m1)(n1)
所以,发生越狱的方案数为 m n − m ∗ ( m − 1 ) ( n − 1 ) m^n-m*(m-1)^{(n-1)} mnm(m1)(n1)
用快速幂即可完成。
【代码展示】

#include<bits/stdc++.h>
#define ud using namespace std
#define ll long long
ud;
ll m,n;
inline long long read()
{
	long long sum=0,flag=1;
	char c;
	for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;
	for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';
	return sum*flag;
}
ll pow(ll a,ll b)
{
	ll tmp=1;
	while(b!=0)
	{
		if(b%2==1)
		{
			tmp*=a;
			tmp%=100003;
		}
		b=b/2;
		a*=a;
		a%=100003;
	}
	return tmp;
}
int main()
{
	m=read();
	n=read();
	ll ans=m*1LL*(pow(m,n-1)-pow(m-1,n-1)+100003)%100003;
	//多加一个100003起到保险作用
	printf("%lld\n",ans);
	return 0;
}

例题2:倒水

【题目描述】
一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子) 显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。 现在CC想知道,最少需要买多少新瓶子才能达到目标呢? 1 < = N < = 1 0 9 , K < = 1000 1<=N<=10^9,K<=1000 1<=N<=109K<=1000
【解析】
显然,由题意我们可以得到,保留瓶子的水容量一定为 2 n ( n ∈ N ∗ ) 2^n(n\in N^*) 2n(nN) ,那么题目就可以转化为求 N N N 的二进制形式中从高位到低位保留 K K K 1 1 1 ,所需要补充的最小差值。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值