扩展欧几里得是用于求解不定方程、线性同余方程和乘法逆元的常用算法。

下面是代码:

 function Euclid(a,b:int64;var x,y:int64):int64;
var t:int64;
begin
if b= then
begin
x:=;y:=;exit(a);
end else
begin
Euclid:=Euclid(b,a mod b,x,y);
t:=x;x:=y;y:=t-(a div b)*y;
end;
end;

下面出现了其中后两个应用。(虽然个人认为不定方程和同余方程可以互相转换)


POJ1061 

  线性同余简单应用。

 program poj1061;
var x0,y0,m,n,L,a,b,d,x,y,tem,c:int64; function f(a:int64):int64;
begin
if a< then a:=a+(-a) div L*L;
while a<= do a:=a+L;
exit(a);
end; function Euclid(a,b:int64;var x,y:int64):int64;
var t:int64;
begin
if b= then
begin
x:=;y:=;exit(a);
end else
begin
Euclid:=Euclid(b,a mod b,x,y);
t:=x;x:=y;y:=t-(a div b)*y;
end;
end; begin
readln(x0,y0,m,n,L);
a:=f(m-n);b:=L;
d:=Euclid(a,b,x,y);
c:=f(y0-x0);
// 由于扩展欧几里得算法里要求最大公约数,所以要处理成正数
// 根据同余方程的性质,a,b,c加上L对答案不会有影响。
if c mod d<> then
begin
writeln('Impossible');
// 同余方程有整数解的条件。
halt;
end;
x:=x*c div d;
if x< then x:=x+(-x) div (b div d)*(b div d);
while x< do x:=x+(b div d);
//这里是保证跳的步数为自然数
if x-(b div d)>= then x:=x-x div (b div d)*(b div d);
while x-(b div d)>= do x:=x-(b div d);
//这里是保证跳的步数是最小步数
writeln(x);
end.

POJ1845

  由于姿势不大对...交了很多遍处理了很多细节才过。

  因此觉得这道题挺好的...因为本来觉得只是一道求逆元的模板题,但实际上想要A掉它并不容易。

  首先先讲一下算法部分。

  求a^b的约数和。

  = (p1^0+p1^1+...p1^k1)*(p2^0+p2^1...+p2^k2)...*(pn^0+pn^1+...pn*kn) (p为a的质因子,ki为第i个质因子的个数)

  我们可以用素数拆分,然后对于每一部分,用等比数列求和公式。

  分子部分可以用取模的快速幂解决。

  分母部分乘上其逆元。

  大体的思路已经构建好了。

  但是细节超级超级多.....>_< 已经被搞疯啦...直接在代码里贴出来好了。


 program poj1845;
const tt=;
var a,b,ans,k:int64;
i:longint; function Euclid(a,b:int64;var x,y:int64):int64;
var t:int64;
begin
if b= then
begin
x:=;y:=;exit(a);
end else
begin
Euclid:=Euclid(b,a mod b,x,y);
t:=x;x:=y;y:=t-(a div b)*y;
end;
end; function mul(a,b:int64):int64;
var ans,w:int64;
begin
ans:=;w:=a mod tt;
while b> do
begin
if b and = then ans:=(ans*w)mod tt;
w:=(w*w) mod tt;
b:=b >> ;
end;
exit(ans);
end; function inverse(p:int64):int64;
var x,y:int64;
begin
if Euclid(p,tt,x,y)<> then exit(-) else
begin
while x<tt do inc(x,tt);
x:=x mod tt;
// 我们需要找到一个正的逆元,根据x= x0+b/d*t可以得到,d=,b=tt。所以只要不停加上tt即可。
// 虽然刚开始的直觉就是不停加上tt直到找到一个正的为止...但是实际上是有理论依据的。
exit(x);
end;
end; begin
while not eof do
// 由于被多组数据坑过...所以不管怎样还是加上为好
begin
readln(a,b);
if a= then
begin
writeln();
// 这是一个细节需要特判
continue;
end;
ans:=;
for i:= to trunc(sqrt(a)) do if a mod i= then
begin
k:=;
while a mod i= do
begin
inc(k);a:=a div i;
end;
k:=k*b;
ans:=((ans*((mul(i,k+)+tt-) mod tt)) mod tt*inverse(i-))mod tt;
// 本来这里的inverse(i-)也需要处理i mod tt=的情况,但是由于数据范围i的上限正好是7000多不用考虑。
end;
// 刚开始下面的一块都忘了QAQ
if a<> then
begin
if a mod tt= then
begin
ans:=ans*(b+) mod tt;
// 这是最容易忽略的一个细节。当a mod tt=的时候,inverse(i)是算不出来的,这个时候思考一下便发现,a mod tt=
// a^k mod tt=,所以最后mod tt余数就是b+.
// 刚开始由于直接输出了(b+) WA了一次...后来发现剩下的a不一定是a本身。
end else
begin
i:=a;k:=b;
ans:=((ans*((mul(i,k+)+tt-) mod tt)) mod tt*inverse(i-)) mod tt;
end;
end;
writeln(ans);
end;
end.

[POJ1845&POJ1061]扩展欧几里得应用两例的更多相关文章

  1. CSU 1446 Modified LCS 扩展欧几里得

    要死了,这个题竟然做了两天……各种奇葩的错误…… HNU的12831也是这个题. 题意: 给你两个等差数列,求这两个数列的公共元素的数量. 每个数列按照以下格式给出: N F D(分别表示每个数列的长 ...

  2. POJ1061 青蛙的约会(扩展欧几里得)

    题目链接:http://poj.org/problem?id=1061 青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

  3. POJ1061:青蛙的约会+POJ2115C Looooops+UVA10673Play with Floor and Ceil(扩展欧几里得)

    http://poj.org/problem?id=1061 第一遍的写法: #include <iostream> #include <stdio.h> #include & ...

  4. [poj1061]青蛙的约会<扩展欧几里得>

    题目链接:http://poj.org/problem?id=1061 其实欧几里得我一直都知道,只是扩展欧几里得有点蒙,所以写了一道扩展欧几里得裸题. 欧几里得算法就是辗转相除法,求两个数的最大公约 ...

  5. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C.Ray Tracing (模拟或扩展欧几里得)

    http://codeforces.com/contest/724/problem/C 题目大意: 在一个n*m的盒子里,从(0,0)射出一条每秒位移为(1,1)的射线,遵从反射定律,给出k个点,求射 ...

  6. UVA 12169 Disgruntled Judge 枚举+扩展欧几里得

    题目大意:有3个整数 x[1], a, b 满足递推式x[i]=(a*x[i-1]+b)mod 10001.由这个递推式计算出了长度为2T的数列,现在要求输入x[1],x[3],......x[2T- ...

  7. UVA 10090 Marbles 扩展欧几里得

    来源:http://www.cnblogs.com/zxhl/p/5106678.html 大致题意:给你n个球,给你两种盒子.第一种盒子每个盒子c1美元,可以恰好装n1个球:第二种盒子每个盒子c2元 ...

  8. POJ 1061 青蛙的约会 扩展欧几里得

    扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...

  9. 【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】

    Problem: n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案.mod 1e9+9 Solution: 这道题由1,2,5,14 应该想到C ...

随机推荐

  1. exchange 2007迁移到2010

    标签:exchange 2007 2010 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zpf666.blog.51cto.c ...

  2. 基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下)

    基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下) 昨天谈到了Mysql实现主从复制,但由于时间原因并未讲有关读写分离的实现,之所以有读写分离,是为了使数据库拥有双机热备功能,至于双 ...

  3. html5判断设备的动作

    相应的事件 deviceorientation事件提供设备的物理方向信息,表示为一系列本地坐标系的旋角. devicemotion事件提供设备的加速信息,表示为定义在设备上的坐标系中的卡尔迪坐标.其还 ...

  4. SQL - SELECT COUNT用法

     SQL Server数据库  COUNT() 函数返回匹配指定条件的行数.   语法   SQL COUNT(column_name) 语法   COUNT(column_name) 函数返回指定列 ...

  5. adb usage

    使用安卓调试及自动化,不可避免的要使用adb,说明看起来很麻烦,进行简单记录,以便时候不时之需. usb连接手机调试就很简单了.首先,在手机端开启usb调试,即点击安卓版本项7次,就可以显示开发者菜单 ...

  6. 容器基础(七): 使用docker compose部署程序

    配置 在上一节的基础上,  增加如下的docker-compose.yml文件, 然后用docker-compose up命令启动容器进行部署: version: " services: s ...

  7. 简历编写技巧-java开发工程师简历实战

    看到一遍简历编写的文章 想到也快找工作了 早晚能够用上 现在摘录如下 640?wx_fmt=jpeg 工欲善其事,必先利其器,这是自古以来的道理.所以如果想找到一份好的工作,一定要先整理一份好的简历. ...

  8. docker基础-虚拟化与容器介绍

    正如所有关心docker技术的人所知道的那样,docker是以容器虚拟化为技术为基础的软件,因此在学习docker具体的内容之前,有必要讨论一下虚拟化和容器技术. 虚拟化技术: 在了解虚拟化技术时,各 ...

  9. lintcode-74-第一个错误的代码版本

    74-第一个错误的代码版本 代码库的版本号是从 1 到 n 的整数.某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错.请找出第一个错误的版本号. 你可以通过 isBad ...

  10. LTE QCI分类 QoS

    http://blog.163.com/gzf_lte/blog/static/20840310620130140057204/ http://blog.163.com/gzf_lte/blog/st ...