poj 2891 求解线性同余方程组
//求解线性同余方程组
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
void ex_gcd(LL a,LL b,LL &d,LL &x0,LL &y0)
{
if(!b)
{
x0=1;
y0=0;
d=a;
return;
}
else {
ex_gcd(b,a%b,d,x0,y0);
LL temp=x0;
x0=y0;
y0=temp-(a/b)*y0;
}
}
int main()
{
LL k;
while(scanf("%lld",&k)==1)
{
if(k==0) continue;
LL a1,r1,m,a2,r2;
bool flag=true;
scanf("%lld%lld",&a1,&r1);
for(LL i=1;i<k;i++)
{
scanf("%lld%lld",&a2,&r2);
LL a=a1,b=a2,c=r2-r1,x0,y0,d;
ex_gcd(a,b,d,x0,y0);
int t=b/d;
if(c%d)
{
flag=false;
}
x0=(x0*(c/d)%t+t)%t;
r1=a1*x0+r1;
a1=(a1/d)*a2; //lcm(a1,a2)
}
if(flag) {
printf("%lld\n",r1);
}
else printf("-1\n");
}
return 0;
}
poj 2115 扩展gcd
//扩展gcd
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
void ex_gcd(LL a,LL b,LL &d,LL &x0,LL &y0)
{
if(b==0)
{
x0=1;
y0=0;
d=a;
return;
}
else {
ex_gcd(b,a%b,d,x0,y0);
LL temp=x0;
x0=y0;
y0=temp-(a/b)*y0;
}
}
int main()
{
LL A,B,C,K;
while(scanf("%lld%lld%lld%lld",&A,&B,&C,&K)==4)
{
if(A==0&&B==0&&C==0&&K==0) break;
LL M=(LL)1<<K,d,x0,y0;
ex_gcd(C,M,d,x0,y0);
LL X=B-A;
if(X%d) {
printf("FOREVER\n");
}
else {
LL ans=X/d*x0;
LL temp=M/d;
cout<<(ans%temp+temp)%temp<<endl;
}
}
return 0;
}
hdu 1573 求解线性同余方程组
//求解一元线性同余方程组
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=15;
LL r1[maxn],a1[maxn];
LL gcd(LL a,LL b)
{
return b==0?a:gcd(b,a%b);
}
void ex_gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(b==0)
{
x=1,y=0;
d=a;
return;
}
else {
ex_gcd(b,a%b,d,x,y);
LL temp=x;
x=y;
y=temp-(a/b)*y;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
LL n,m,lcm=1;
scanf("%lld%lld",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%lld",&a1[i]);
lcm=lcm/gcd(lcm,a1[i])*a1[i];
}
for(int i=0;i<m;i++)
{
scanf("%lld",&r1[i]);
}
bool flag=true;
LL d,x0,y0;
for(int i=1;i<m;i++)
{
LL a=a1[i-1],b=a1[i],c=r1[i]-r1[i-1];
ex_gcd(a,b,d,x0,y0);
if(c%d) {
flag=false;
break;
}
else {
LL t=b/d;
x0=(x0*(c/d)%t+t)%t;
r1[i]=a1[i-1]*x0+r1[i-1];
a1[i]=(a1[i]/d)*a1[i-1];
}
}
LL ans=0;
if(flag) { //找到在最小公倍数内的一个非负整数解
if(r1[m-1]>0&&r1[m-1]<=n) ans++;
LL k=(n-r1[m-1])/lcm;
ans+=k;
cout<<ans<<endl;
}
else {
printf("0\n");
}
}
return 0;
}
hdu 3579 求解线性同余方程组
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━━━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* █████━█████ ┃+
* ┃ ┃ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━━┓ ┏━┛
* ┃ ┃
* ┃ ┃ + + + +
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ + 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃ +
* ┃ ┗━━━┓ + +
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━━━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
//http://www.swifthumb.com/thread-674-1-1.html
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \\| |// `.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Buddha Bless, No Bug !
//
// .::::.
// .::::::::.
// :::::::::::
// ..:::::::::::'
// '::::::::::::'
// .::::::::::
// '::::::::::::::..
// ..::::::::::::.
// ``::::::::::::::::
// ::::``:::::::::' .:::.
// ::::' ':::::' .::::::::.
// .::::' :::: .:::::::'::::.
// .:::' ::::: .:::::::::' ':::::.
// .::' :::::.:::::::::' ':::::.
// .::' ::::::::::::::' ``::::.
// ...::: ::::::::::::' ``::.
// ```` ':. ':::::::::' ::::..
// '.:::::' ':'````..
//
//
// ┏┛ ┻━━━━━┛ ┻┓
// ┃ ┃
// ┃ ━ ┃
// ┃ ┳┛ ┗┳ ┃
// ┃ ┃
// ┃ ┻ ┃
// ┃ ┃
// ┗━┓ ┏━━━┛
// ┃ ┃ 神兽保佑
// ┃ ┃ 代码无BUG!
// ┃ ┗━━━━━━━━━┓
// ┃ ┣┓
// ┃ ┏┛
// ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
// ┃ ┫ ┫ ┃ ┫ ┫
// ┗━┻━┛ ┗━┻━┛
//求解一元线性同余方程组
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=15;
LL r1[maxn],a1[maxn];
LL gcd(LL a,LL b)
{
return b==0?a:gcd(b,a%b);
}
void ex_gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(b==0)
{
x=1,y=0;
d=a;
return;
}
else {
ex_gcd(b,a%b,d,x,y);
LL temp=x;
x=y;
y=temp-(a/b)*y;
}
}
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
LL m,lcm=1;
scanf("%lld",&m);
for(int i=0;i<m;i++)
{
scanf("%lld",&a1[i]);
lcm=lcm/gcd(lcm,a1[i])*a1[i];
}
for(int i=0;i<m;i++)
{
scanf("%lld",&r1[i]);
}
printf("Case %d: ",++kase);
bool flag=true;
LL d,x0,y0;
for(int i=1;i<m;i++)
{
LL a=a1[i-1],b=a1[i],c=r1[i]-r1[i-1];
ex_gcd(a,b,d,x0,y0);
if(c%d) {
flag=false;
break;
}
else {
LL t=b/d;
x0=(x0*(c/d)%t+t)%t;
r1[i]=a1[i-1]*x0+r1[i-1];
a1[i]=(a1[i]/d)*a1[i-1];
}
}
//输出最小正整数
if(flag) { //找到在最小公倍数内的一个非负整数解
if(r1[m-1]==0) r1[m-1]+=lcm; //特殊情况
cout<<r1[m-1]<<endl;
}
else {
printf("-1\n");
}
}
return 0;
}
poj 3243 求解高次同余方程 使用BSGS算法
//求解高次同余方程
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL __int64
#define N 1000000
using namespace std;
struct Node{
LL idx;
LL val;
}baby[N];
bool cmp(Node n1,Node n2){
return n1.val!=n2.val?n1.val<n2.val:n1.idx<n2.idx;
}
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
LL extend_gcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1;
y=0;
return a;
}
LL gcd=extend_gcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return gcd;
}
LL inval(LL a,LL b,LL n){
LL e,x,y;
extend_gcd(a,n,x,y);
e=((LL)x*b)%n;
return e<0?e+n:e;
}
LL PowMod(LL a,LL b,LL MOD){
LL ret=1%MOD,t=a%MOD;
while(b){
if(b&1)
ret=((LL)ret*t)%MOD;
t=((LL)t*t)%MOD;
b>>=1;
}
return (LL)ret;
}
LL BinSearch(LL num,LL m){
LL low=0,high=m-1,mid;
while(low<=high){
mid=(low+high)>>1;
if(baby[mid].val==num)
return baby[mid].idx;
if(baby[mid].val<num)
low=mid+1;
else
high=mid-1;
}
return -1;
}
LL BabyStep(LL A,LL B,LL C){
LL tmp,D=1%C;
LL temp;
for(int i=0,tmp=1%C;i<100;i++,tmp=((LL)tmp*A)%C)
if(tmp==B)
return i;
LL d=0;
while((temp=gcd(A,C))!=1){
if(B%temp) return -1;
d++;
C/=temp;
B/=temp;
D=((A/temp)*D)%C;
}
LL m=(int)ceil(sqrt((double)C));
for(int i=0,tmp=1%C;i<=m;i++,tmp=((LL)tmp*A)%C){
baby[i].idx=i;
baby[i].val=tmp;
}
sort(baby,baby+m+1,cmp);
LL cnt=1;
for(int i=1;i<=m;i++)
if(baby[i].val!=baby[cnt-1].val)
baby[cnt++]=baby[i];
LL am=PowMod(A,m,C);
for(int i=0;i<=m;i++,D=((LL)(D*am))%C){
LL tmp=inval(D,B,C);
if(tmp>=0){
LL pos=BinSearch(tmp,cnt);
if(pos!=-1)
return i*m+pos+d;
}
}
return -1;
}
int main(){
LL A,B,C;
while(scanf("%lld%lld%lld",&A,&C,&B)!=EOF){
if(!A&&!B&&!C) break;
LL ans=BabyStep(A,B,C);
if(ans<0)
printf("No Solution\n");
else
printf("%d\n",ans);
}
return 0;
}
poj 2417 求解高次同余方程
//求解高次同余方程
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL __int64
#define N 1000000
using namespace std;
struct Node{
LL idx;
LL val;
}baby[N];
bool cmp(Node n1,Node n2){
return n1.val!=n2.val?n1.val<n2.val:n1.idx<n2.idx;
}
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
LL extend_gcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1;
y=0;
return a;
}
LL gcd=extend_gcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return gcd;
}
LL inval(LL a,LL b,LL n){
LL e,x,y;
extend_gcd(a,n,x,y);
e=((LL)x*b)%n;
return e<0?e+n:e;
}
LL PowMod(LL a,LL b,LL MOD){
LL ret=1%MOD,t=a%MOD;
while(b){
if(b&1)
ret=((LL)ret*t)%MOD;
t=((LL)t*t)%MOD;
b>>=1;
}
return (LL)ret;
}
LL BinSearch(LL num,LL m){
LL low=0,high=m-1,mid;
while(low<=high){
mid=(low+high)>>1;
if(baby[mid].val==num)
return baby[mid].idx;
if(baby[mid].val<num)
low=mid+1;
else
high=mid-1;
}
return -1;
}
LL BabyStep(LL A,LL B,LL C){
LL tmp,D=1%C;
LL temp;
for(int i=0,tmp=1%C;i<100;i++,tmp=((LL)tmp*A)%C)
if(tmp==B)
return i;
LL d=0;
while((temp=gcd(A,C))!=1){
if(B%temp) return -1;
d++;
C/=temp;
B/=temp;
D=((A/temp)*D)%C;
}
LL m=(int)ceil(sqrt((double)C));
for(int i=0,tmp=1%C;i<=m;i++,tmp=((LL)tmp*A)%C){
baby[i].idx=i;
baby[i].val=tmp;
}
sort(baby,baby+m+1,cmp);
LL cnt=1;
for(int i=1;i<=m;i++)
if(baby[i].val!=baby[cnt-1].val)
baby[cnt++]=baby[i];
LL am=PowMod(A,m,C);
for(int i=0;i<=m;i++,D=((LL)(D*am))%C){
LL tmp=inval(D,B,C);
if(tmp>=0){
LL pos=BinSearch(tmp,cnt);
if(pos!=-1)
return i*m+pos+d;
}
}
return -1;
}
int main(){
LL A,B,C;
while(scanf("%lld%lld%lld",&C,&A,&B)!=EOF){
//if(!A&&!B&&!C) break;
LL ans=BabyStep(A,B,C);
if(ans<0)
printf("no solution\n");
else
printf("%d\n",ans);
}
return 0;
}
hdu 2815 高次同余方程
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL __int64
#define N 1000000
using namespace std;
struct Node{
int idx;
int val;
}baby[N];
bool cmp(Node n1,Node n2){
return n1.val!=n2.val?n1.val<n2.val:n1.idx<n2.idx;
}
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int extend_gcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int gcd=extend_gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return gcd;
}
int inval(int a,int b,int n){
int e,x,y;
extend_gcd(a,n,x,y);
e=((LL)x*b)%n;
return e<0?e+n:e;
}
int PowMod(int a,int b,int MOD){
LL ret=1%MOD,t=a%MOD;
while(b){
if(b&1)
ret=((LL)ret*t)%MOD;
t=((LL)t*t)%MOD;
b>>=1;
}
return (int)ret;
}
int BinSearch(int num,int m){
int low=0,high=m-1,mid;
while(low<=high){
mid=(low+high)>>1;
if(baby[mid].val==num)
return baby[mid].idx;
if(baby[mid].val<num)
low=mid+1;
else
high=mid-1;
}
return -1;
}
int BabyStep(int A,int B,int C){
LL tmp,D=1%C;
int temp;
for(int i=0,tmp=1%C;i<100;i++,tmp=((LL)tmp*A)%C)
if(tmp==B)
return i;
int d=0;
while((temp=gcd(A,C))!=1){
if(B%temp) return -1;
d++;
C/=temp;
B/=temp;
D=((A/temp)*D)%C;
}
int m=(int)ceil(sqrt((double)C));
for(int i=0,tmp=1%C;i<=m;i++,tmp=((LL)tmp*A)%C){
baby[i].idx=i;
baby[i].val=tmp;
}
sort(baby,baby+m+1,cmp);
int cnt=1;
for(int i=1;i<=m;i++)
if(baby[i].val!=baby[cnt-1].val)
baby[cnt++]=baby[i];
int am=PowMod(A,m,C);
for(int i=0;i<=m;i++,D=((LL)(D*am))%C){
int tmp=inval(D,B,C);
if(tmp>=0){
int pos=BinSearch(tmp,cnt);
if(pos!=-1)
return i*m+pos+d;
}
}
return -1;
}
int main(){
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF){
if(B>=C){
puts("Orz,I can’t find D!");
continue;
}
int ans=BabyStep(A,B,C);
if(ans==-1)
puts("Orz,I can’t find D!");
else
printf("%d\n",ans);
}
return 0;
}