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

下面是代码:

 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. 在编程的时候,NotePad++ 中闪烁的光标突然有竖着闪烁的编程蓝色下划线闪烁的--小技巧告诉你-费元星

    当在写代码时出现的光标闪烁(横线闪烁) 在键盘上找 Insert ,按这个Insert就可以把横向闪烁光标( _ )修改成竖向闪烁光标样式( | ),横向光标会在你写代码的时候修改前面的代码,把光标移 ...

  2. python简单的数据清洗,数据筛选方法归类

    创建数组有两种方式,1.直接赋值 2.随机变量生成随机生成包括4种:np.arange(20),np.linspace(0,10,5),np.logspace(0,2,5),np.random.ran ...

  3. 玩转Vim-札记(一)

    玩转Vim-札记(一) 简介 在这个蔚蓝色的星球上,流传着两大神器的传说:据说Emacs是神的编辑器,而Vim是编辑器之神.一些人勇敢地拾起了Vim或Emacs,却发现学习曲线陡峭而漫长,还是有一些人 ...

  4. Android Studio Gradle编译时『No resource found that matches the given name』解决方法(windows系统的坑)

    * 最近帮团队同事配置gradle时,发现一个非常奇怪的问题:> * 同样的gradle配置的项目,只是修改了一个项目的名称,竟然会出现以下奇怪问题: ## 现象1. 一个编译完全OK,另外一个 ...

  5. Qt 汽车仪表 QWidget

    今天是2016年的最后一个工作日,在这个最后工作日里面,和以为网友要了一点练手的素材文件,经过网友确认,不涉及商业机密,在这里分享一下,如侵权,请联系我删除. 先上程序运行图 这里显示数字,闪烁等都没 ...

  6. LLLYYY的数字思维(模拟题)

    链接:https://ac.nowcoder.com/acm/contest/318/G LLLYYY很喜欢写暴力模拟贪心思维.某一天在机房,他突然抛给了队友ppq一 个问题.问题如下: 有一个函数f ...

  7. 今日头条 2018 AI Camp 视频面试

    1. 本次面试是在牛客网平台进行的,没有涉及到技术细节,面试官也说仅仅是聊天.但是,不知道是网络卡顿还是平台缘故,连接非常不稳定,经常听不到声音,对方那边噪音也特别大,面试体验不是很好. 2. 面试时 ...

  8. android问题笔记集

    开发工具:android studio2.2 调试:手机直连调试,版本(android6) 问题1: Error:Unable to start the daemon process. This pr ...

  9. 树莓派初次使用的基本配置.md

    记录了一下树莓派初次使用的配置过程,包括装系统.修改 IP 等等. 树莓派(英语:Raspberry Pi),是一款基于 Linux 的单板机电脑. 它由英国的树莓派基金会所开发,目的是以低价硬件及自 ...

  10. Week1 Team Homework #1 from Z.XML-项目选择思路--基于对曾经大作业项目的思考

    这两天试玩了一下去年学长的满分工程<shield star>游戏,再结合了一下他们团队的博客记录,有一种非常牛逼的感觉.具体对于这款游戏的一些思考和看法,毛大神已经说的很好了.因此,这里主 ...