[POJ1845&POJ1061]扩展欧几里得应用两例
扩展欧几里得是用于求解不定方程、线性同余方程和乘法逆元的常用算法。
下面是代码:
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]扩展欧几里得应用两例的更多相关文章
- CSU 1446 Modified LCS 扩展欧几里得
要死了,这个题竟然做了两天……各种奇葩的错误…… HNU的12831也是这个题. 题意: 给你两个等差数列,求这两个数列的公共元素的数量. 每个数列按照以下格式给出: N F D(分别表示每个数列的长 ...
- POJ1061 青蛙的约会(扩展欧几里得)
题目链接:http://poj.org/problem?id=1061 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
- POJ1061:青蛙的约会+POJ2115C Looooops+UVA10673Play with Floor and Ceil(扩展欧几里得)
http://poj.org/problem?id=1061 第一遍的写法: #include <iostream> #include <stdio.h> #include & ...
- [poj1061]青蛙的约会<扩展欧几里得>
题目链接:http://poj.org/problem?id=1061 其实欧几里得我一直都知道,只是扩展欧几里得有点蒙,所以写了一道扩展欧几里得裸题. 欧几里得算法就是辗转相除法,求两个数的最大公约 ...
- 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个点,求射 ...
- 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- ...
- UVA 10090 Marbles 扩展欧几里得
来源:http://www.cnblogs.com/zxhl/p/5106678.html 大致题意:给你n个球,给你两种盒子.第一种盒子每个盒子c1美元,可以恰好装n1个球:第二种盒子每个盒子c2元 ...
- POJ 1061 青蛙的约会 扩展欧几里得
扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...
- 【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】
Problem: n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案.mod 1e9+9 Solution: 这道题由1,2,5,14 应该想到C ...
随机推荐
- Cyclone IV器件的逻辑单元和逻辑阵列快
1. 逻辑单元 (LE) 在 Cyclone IV 器件结构中是最小的逻辑单位.LE 紧密且有效的提供了高级功能的逻辑使用.每个 LE 有以下特性:一个四口输入的查找表 (LUT),以实现四种变量的任 ...
- js复制粘贴事件
一.相应的事件 copy: 在发生复制操作时触发. beforecut: 在发生剪切操作 前 触发. cut: 在 发生 剪切 操作 时 触发. beforepaste: 在 发生 粘贴 操作 前 触 ...
- vue2.0 watch
类型:string | Function | Object vue官网解释: 一个对象,键是需要观察的表达式,值是对应回调函数.值也可以是方法名,或者包含选项的对象.Vue 实例将会在实例化时调用 $ ...
- CDateTimeUI类源码分析
CDateTimeUI是duilib里选择日期的控件,继承于CLabelUI控件,用于记录已经选择的日期,选择控件则是调用win32的日期选择控件. CDateTimeUI包含两个类,一个是CDate ...
- ES6 语法糖
重新认识ES6中的语法糖:https://segmentfault.com/a/1190000010159725
- TP5 急速上手 语法规则
Tp5 规则 命名规范 目录和文件名采用‘小写+下划线’,并且以小写字母开头: 类库.函数文件统一以.php为后缀: 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致(包括大小写 ...
- gcc options选项的优化及选择
gcc options选项的优化 -c和-o都是gcc编译器的可选参数[options] -c表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件,一般是.o文件.[只 ...
- ubuntu 开热点
原文地址:https://www.cnblogs.com/king-ding/archive/2016/10/09/ubuntuWIFI.html 今天教大家一个简单方法让ubuntu发散wifi热点 ...
- wangEditor编辑器中解析html图文信息问题
在JS中,有一种方法:innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML. 也就是说,我们可以利用这个属性,把字符串转换为html代码,这样就可以被解析了. 其次,我们是需要在页 ...
- 预研报告——MyBatis持久层的demo
一.预研任务介绍和预研目标 任务介绍: 与 Hibernate 相比, MyBatis 是一个半自动化的持久层框架,以轻量级.效率高.原生代而好评如潮.虽然有在分享会上大致讲解,但是还是重新梳理成文字 ...