数学类总结

打了一个月的数学酱油,总算将大概的数学问题马马虎虎地过了一遍,由于自己训练的进度问题,这方面的加强留在下阶段的刷题练习。

数论:欧几里德,扩展欧几里德,素数,素数分解,欧拉函数,线性同余,剩余定理,解模线性方程组等,经典的一些数论算法就这些吧。但数论绝不止这么点,一些数论的定理、性质及证明过程都是非常重要的,通常需要用数论的一些性质和推理思想解决问题,很重要。于是要好好练,加强在路上

说说题目:

Pku2635 The Embarrassed Cryptographer

题意简述:给定nl,求n是否存在小于l的素因子。

不难,1000进制高精度取余。

 

Pku3292 Semi-prime H-numbers

题意简述:找区间内的H-sumi-prime,不是一般的prime

根据题意所给的性质筛选,和筛选素数差不多。

 

pku1845 Sumdiv

题意简述:求a^b的因子和。

首先推推因子和的公式,对于一个数n,可以唯一分解成n=a1^b1*a2^b2……ak^bk这样的形式,那么n的因子和的公式为:(1+a1+a1^2+……+a1^b1)*……*(1+ak+……ak^bk)。这个公式至于为什么,展开看看就知道了。于是对于这题先将a^b 分解成上述形式,观察一下数据的范围,后面的计算部分显然不允许硬搞。

对于fn=1+a+a^2+……a^n:当n为奇数时:可以化为 (1+a^(n+1)/2) *f(n/2)

n为偶数时:可化为 f((n-1)/2)+a^n/2*(1+a*f((n-1)/2))

于是可以用分治的方法来求解。

 

Pku2115 C Looooops

题意简述:解模线性方程A+CxB(mod 2^k)

将上式化成Cx(B-A)(mod 2^k),为了避免负数将等式改成Cx(B-A+2^k)(mod 2^k)不会影响求解的结果。设D=2^k,根据求解的性质,当gcd(C,D)|(B-A) 时有解。于是根据求解方法,先可用扩展欧几里德求出Cx+Dy=(B-A),中的x值,由此可得第一个解为x*(B-A)/gcd(C,D),加D再对D取模即可到最小正整数解。(后面的解逐一加(B-A)/gcd)。

Psex-Euclid()

__int64 ex_Euclid(__int64 A,__int64 B)

{

    if(B==0)

    {

        x=1;

        y=0;

        return A;

    }

    __int64 dd;

    dd=ex_Euclid(B,A%B);

    __int64 t=x;

    x=y;

    y=t-(A/B)*x;

    return dd;

}

 

Pku3517 Pseudoprime numbers

题意简述:求解a^p=a(mod)p是否有解。p为素数的不考虑,然后就是二分求解a^p(mod p)

Ps:一段二分求解的代码:

__int64 Mod(__int64 a,__int64 p,__int64 b)

{

    __int64 ans=1;

    __int64 tmp=a;

    while(p)

    {

        if(p&1) ans=(ans*tmp)%b;

        tmp=tmp*tmp%b;

        p>>=1;

    }

    return ans;

}

 

Pku2891 Strange Way to Express Integers

求解同余线性方程组x=ai(mod ri),这个不能用通常的方法书上讲的方法去解,因为不能保证ri之间两两互质,所以需要逐步的去求解。

 

Pku1597 Uniform Generator

题目大概就是求ax(mod b) 能否完全覆盖(mod b) 的剩余系,这个我们可以根据《算法导论》上对剩余系的叙述上得出,只有当gcd(a,b)=1的时候才会满足。

 

Pku3619 Speed Reading

水题,心情不好的时候用来练手的。

 

Pku2478 Farey Sequence

求法雷级数的个数。也就是求Euler函数吧,显然Euler函数一般不能用暴力的求法,通过这题学会快速求Euler函数。

 

Pku3090 Visible Lattice Points

n*n区域内的所有点,连线原点能形成多少中斜率。根据斜率的计算方法,可以知道就是通过Euler函数来判断当前点与前面出现的点斜率不同的有多少种,然后求解。

 

Pku3191 The Moronic Cowmpouter

10进制转换成-2进制,根据一般的转换定义计算即可。

 

Pku1284 Primitive Roots

求一个数的原根,直接根据定理解。

h为一整数,n为一正整数,(hn=1,适合h^l=1mod n)的最小正整数l叫做hn的次数。如果l=φn)(φn)是欧拉函数,表示与n互素且不超过n的正整数的个数),则此时h被称为模n的原根。1773年,欧拉证明了素数P有原根。1785年,勒让德证明:设l |p-1),恰有φ(l)个模p互不同余的数对模p的次数为l。那么这题的情况恰好就是l=p-1

 

Pku2407 Relatives

非常裸的Euler函数求解,继续练习Euler

 

Pku2773 Happy 2006

求第k个与n互质的数,由于数据比较大,只能推出公式直接算,水!。

 

Pku3358 Period of an Infinite Binary Expansion

10进制分数转换二进制分数的循环节,这题比较难,模型比较经典,在forerverlin大神的提示下做出来的,附一份大神的解题思路:

//p/q =p/(r*2^m)=(t+k*r)/(r*2^m)=(t/r+k)/(2^m)

//t=p%r p,q互质可知,tr也互质,否则还可以继续约分,而k为整数,对求小数部分没影响,又1/(2^m)只会使小数点向左偏移

//只影响循环节的起始位置,对长度没影响,r,t,2,这三个数相互互质,可知t/r的循环节起始位置为1,又因为小数点左移m

//因此p/q的循环节起始位置为m+1

//(3)求循环节长度,现在等价于求t/r的循环节长度,再一次转化,等价于求满足(t*2^k)%r==t%r(根据k进制的定义)

//化简得t%r*(2^k%r)=t%r,等价于为求满足2^k = 1(mod r)的最小k值。

//由欧拉定理可知k必为phi(r)的约数,所以可以先生成r的所有约数,再枚举r的约数看是否满足2^k=1(mod r) 

 

Pku2992 Divisors

Cnk 的因子个数,对于一个数n个因子个数,我们可以先对n进行因子分解,用素数乘积的形式唯一表示,在该乘积项中设指数分别为a1a2……ak,那么n的因子个数就是:(a1+1)*(a2+1)*……*(ak+1)。那么这题可以类似的求解,这里求n!的含prime[i]的个数有一种很经典的求法:

int col(int n,int k)  //n表是n!,k表示某个素数
{
    if(n<k) return 0;
    return (n/k+col(n/k,k));
}

慢慢体会一下。

 

Pku3492 Knapsack II

求不能由给定的n个数表示的最大整数,且这n个数的系数不小于0

剩余系+最短路。

数学模型为:a1*x1+a2*x2...an*xn=Sx1,x2,x3..xn)有非负解的S的最小值

也就是说找出一个下界,使得之后所有的值都能表示出来

对于D=gcd(a1,a2...an),如果D不等于1,那么这个下界是不会出现的,即INF

接下对D=1情况下进行分析 ,找出最小的数,其他数对其按同余类进行分类,这样一共有a1个同余类(令a1为最小)

每个同余类是存在一个最小值的,有了这个最小值,其他的数我们可以通过+n*a1来获得,这样我们可以看成是a1个节点

用单原点最短路径求0号节点到其余节点的最短路径。所得结果就是该同余类的最小值

节点编号为其所在同余类的编号,如过同余类(x+w==同余类(y,那么我们可以通过一条路径到达同余类y

那么问题就转化成了从同余类0号节点到各个同余类的最短距离,取最大的那个减去最小值即为所求。

 

 

高斯消元

Pku1222 && pku1681 && pku1830&&hdu3364

上面几道题目可以称为经典的几道“关灯问题”,可以构造矩阵求解Ax=B,每行表示一个节点的状况(表示能影响这个节点状态的描述),那么等式的右边就是他需要达到的状态,那么就是一个齐次线性方程的求解,直接高斯消元,高斯消元的具体实现看看线性代数或百度百科,找个好一点的模版体会一下就行了。由于模版太搓了,不贴了。

 

 

区间计数

这类问题不难,但是太麻烦了,稍不小心就会漏掉需要考虑的情况,多练吧。

Pku2282 The Counting Problem

求给定区间里,出现0~9的次数。首先看看不考虑0的情况,n为数那么0~9各个数字出现的次数必定相等,为n*10^(n-1)。那么后面的就是体力活了。。。

 

 

组合数学

Pku2356 Find a multiple

给一列n数,求连续一段长度小于等于n的序列,使得这段和能被n整除。其实这就是一个经典的鸽巢原理,由于n个从1开始到ai,有n段,而若不考虑对n取模为0的情况(因为等于就直接满足题意了),有n-1个取值,那么这n段的和对n取模必定有相同的情况。于是设si=a1+a2+……+aisl=a1+a2+……al。令si=a*n+rsl=b*n+r。那么通过sl-si就会发现怎么求解了。。。

 

Hdu2588 GCD

这题需要根据容斥原理解决,对于正方形的情况直接上Euler函数,对于长方形的情况就需要容斥原理,对于这题的应用比较经典,贴代码回顾:

 

 

Pku2409 && pku1286

经典的polya计数,还是比较裸的,先试试手。确定置换群,用gcd寻找循环指数,那么就可以求解了。

 

Pku2154 Color

与上两题类似,polya计数,但看到数据范围明显就不能用同样的方法来解了,需要用Euler函数来加速,结果为:1/n*sum(Euler(i)*n^(n/i)),这个很容易理解的。求模的时候同样需要用到二分。于是解决,hnu11426也是一道类似的题目,但是置换群不同,稍微该一下就可以过。

 

 

稳定婚姻问题

Pku3487The Stable Marriage Problem

经典的稳定婚姻问题,就是用男的先去找当前没拒绝他的最心爱的女的,如果男的都找到了心怡的对象,匹配就结束;否则,继续继续在下次进行类似选择,而女的就会选在向她表白当中选最心怡的对象。于是可以用队列模拟实现这个算法,至于证明过程,见组合数学。

 

 

博弈

Pku1067 取石子游戏

这题是经典的博弈,有公式的:ai=i*sqrt(5)+1/2

于是简单求解,至于证明过程真不会,自己推到一半就无法下手了,后来才知道与黄金分割都挂钩了,无法想。。。

 

Pku2234 Matches Game

经典的Nim游戏博弈问题,对n个数一次做异或运算,为0则为奇异状态,否则不是。那么就可求解了。至于Nim游戏定理的证明,数学归纳法就能得证。

 

Pku1704 Georgia and Bob

这题看起来有点像Nim问题,但是不能把取出来的完全忽略,但还是可以转换一下,想想楼梯博弈。。发现奇像,于是从最后一个开始,算奇数位的异或和,为0即为奇异状态,否则不是。证明:对于奇数位,我们可以相当对其做Nim游戏,把取出来的都丢到偶数位,Nim完以后,所有的数都在偶数位,对手如果把偶数位的数丢到奇数位(Nim的过程中,也可如此),我们反着可以把丢进来的数再丢到偶数位,这样就能保证先走必胜。

 

Pku1082 Calendar Game

日历游戏,也可以算是一道博弈吧,但我确是用模拟的过程在推状态,弱。。。

 

Pku2348 Euclid's Game

同样也是一道博弈,也就是推小数据,划分状态区间,证明,然后求解。

Psac后,才发现这题取这个名字是有原因的,给出的样例示范也很具有提示性,求解过程也印证了题目名。

 

Pku1085 Triangle War

博弈搜索,不过这题却是用的记忆化搜索,没用到什么alpha-beta剪枝。

Pku3317是道不错的博弈剪枝,不过tle了,可能还有一些剪枝情况没考虑到。

Psalpha-beta的模版):

总结完了,显然感觉到了没好多东西,依然太弱,需要不断做题、做比赛训练,加强在路上。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值