SGU 140 扩展欧几里得
题目大意:
给定序列a[] , p , b
希望找到一个序列 x[] , 使a1*x1 + a2*x2 + ... + an*xn = b (mod p)
这里很容易写成 a1*x1 + a2*x2 + ... + an*xn + yp = b
-> a1*x1 + a2*x2 + ... + an*xn + y1*p + y2*p + .... + yn*p = b
->(a1*x1+y1*p) + (a2*x2+y2*p) + ... + (an*xn+yn*p) = b
y[]是必然有解的 , 这里每一个值都可以看做一个二元方程,用扩展欧几里得求解得到的就是
f1*gcd(a1,p) + f2*gcd(a2,p) + ... + fn*gcd(an,p) = b (1.1)
这里f[]是未知的 ,只要求扩展欧几里得的过程中记录当答案为ai*xi + yi*p = gcd(ai,p) 是xi的值
那么求出合法的fi , 那么正确的解就是 xi = xi*fi
而式子1.1又可以逐个求扩展欧几里得,然后再逆向求回来
ll cur = b;
bool flag=true;
for(int i=n ; i>=1 ; i--){
ll tmp;
ll d = ex_gcd(t[i-1] , tmp , g[i] , f[i]);
if(cur%d!=0){flag=false;break;}
f[i] = cur/d*f[i];
cur -= f[i]*g[i];
}
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <set>
#include <iostream>
using namespace std; #define ll long long
int n , p , b;
int a[];
ll g[] , x[] , y[];
ll t[] , f[]; ll ex_gcd(ll a , ll &x , ll b , ll &y)
{
if(b==){
x = , b = ;
return a;
}
ll ans = ex_gcd(b , x , a%b , y);
ll t=x ;
x=y , y=t-(a/b)*y;
return ans;
} ll gcd(ll a , ll b){return b?gcd(b,a%b):a;} int main()
{
scanf("%d%d%d" , &n , &p , &b);
for(int i= ; i<=n ; i++){
scanf("%d" , &a[i]);
g[i] = ex_gcd(a[i] , x[i] , p , y[i]);
} t[] = , t[] = g[];
for(int i= ; i<=n ; i++){
t[i] = gcd(t[i-], g[i]);
}
if(b%t[n]!=){
puts("NO");
return ;
}
ll cur = b;
bool flag=true;
for(int i=n ; i>= ; i--){
ll tmp;
ll d = ex_gcd(t[i-] , tmp , g[i] , f[i]);
if(cur%d!=){flag=false;break;}
f[i] = cur/d*f[i];
cur -= f[i]*g[i];
}
if(!flag) {
puts("NO");
return ;
}
puts("YES");
for(int i= ; i<=n ; i++){
ll v = x[i]*f[i];
v = (v%p+p)%p;
if(i<n) printf("%I64d " , v);
else printf("%I64d\n" , v);
}
return ;
}
SGU 140 扩展欧几里得的更多相关文章
- SGU 106 The equation 扩展欧几里得好题
扩展欧几里得的应用……见算法竞赛入门经典p.179 注意两点:1.解不等式的时候除负数变号 2.各种特殊情况的判断( a=0 && b=0 && c=0 ) ( a=0 ...
- 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 ...
- poj 2891 扩展欧几里得迭代解同余方程组
Reference: http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html 之前说过中国剩余定理传统解法的条件是m[i]两两互 ...
- poj 2142 扩展欧几里得解ax+by=c
原题实际上就是求方程a*x+b*y=d的一个特解,要求这个特解满足|x|+|y|最小 套模式+一点YY就行了 总结一下这类问题的解法: 对于方程ax+by=c 设tm=gcd(a,b) 先用扩展欧几里 ...
- poj 1061 扩展欧几里得解同余方程(求最小非负整数解)
题目可以转化成求关于t的同余方程的最小非负数解: x+m*t≡y+n*t (mod L) 该方程又可以转化成: k*L+(n-m)*t=x-y 利用扩展欧几里得可以解决这个问题: eg:对于方程ax+ ...
随机推荐
- iOS开发之 Xcode svn更新代码后,不能打开.xcodeproj,因为该项目文件不能被解析
http://www.cfanz.cn/?c=article&a=read&id=41565 解决方法: 1.对.xcodeproj 文件右键,显示包内容 2.双击打开 proj ...
- D3.js 第一个程序 HelloWorld
一.HTML 是怎么输出 HelloWorld 的 <html> <head> <meta charset="utf-8"> <title ...
- Htmlt_Div+Css简介
DIV+CSS是网站标准(或称“WEB标准”)中常用术语之一,通常为了说明与HTML网页设计语言中的表格(table)定位方式的区别,因为XHTML网站设计标准中,不再使用表格定位技术,而是采用DIV ...
- Myeclipse6.5项目启动时由于数据库连接失败的错误日志
Java HotSpot(TM) 64-Bit Server VM warning: MaxNewSize (524288k) is equal to or greater than the enti ...
- hiho1123_好配对
题目 给定两个序列a和b,每个序列中可能含有重复的数字. 一个配对(i,j)是一个好配对当从第一个序列中选出一个数ai,再从第二个序列中选出一个数bj且满足ai>bj. 给出两个序列,问存在多少 ...
- Python开发者须知 —— Bottle框架常见的几个坑
Bottle是一个小巧实用的python框架,整个框架只有一个几十K的文件,但却包含了路径映射.模板.简单的数据库访问等web框架组件,而且语法简单,部署方便,很受python开发者的青睐.Pytho ...
- Android 为PopupWindow设置动画效果
首先定义显示效果的动画文件: <?xml version="1.0" encoding="utf-8"?> <set xmlns:androi ...
- 如何进行shell脚本正确性测试
在实际工作中,需要对shell脚本进行正确性测试. 如何用最快最有效的方式进行测试? 很多开发的习惯是,二话不说,写完/拿到,就跑一把,看看输入,输出,想要的操作是否完成,也就过了. 其实这是十分不严 ...
- javaWeb1 tomcat
tomcat使用常见问题: 1.闪退: 原因:tomcat 软件是由java语言开发的,当它启动时,会默认到系统 的环境变量中查找 JAVA_HOME 的变量.找它的目的时tomcat 启动 时需要j ...
- 华为面试题——一道关于指针方面的编程题(C/C++)
int A[nSize],其中隐藏着若干0,其余非0整数,写一个函数int Func(int* A, int nSize),使A把0移至后面,非0整数移至数组前面并保持有序,返回值为原数据中第一个元素 ...