线性同余方程+高次同余方程

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;
}

猜你喜欢

转载自blog.csdn.net/m0_37428263/article/details/81263066
今日推荐