zoukankan      html  css  js  c++  java
  • exBSGS学习笔记

    前置知识

    大步小步定理

    以及是个人都会的exgcd

    Problem

    洛谷P4195 【模板】exBSGS/Spoj3105 Mod

    Solution

    [a^xequiv bmod p\ a imes a^{x-1}equiv bmod p\ 令X=a^{x-1}\ herefore a·X+p·Y=b\ exgcd求出X\ 令d=gcd(a,p)\ frac ad*Xequiv frac bdmod frac pd\ Xequivfrac bd*frac damod frac pd\ a^{x-1}equivfrac bamod frac pd\ ]

    Code

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    struct Hashmap{
    	static const int MAXINT=((1<<30)-1)*2+1,Ha=999917,maxe=46340;
    	int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5];
    	int top,stk[maxe+5];
    	void clear(){
    		E=0;
    		while(top)
    		lnk[stk[top--]]=0;
    	}
    	void Add(int x,int y){
    		son[++E]=y;
    		nxt[E]=lnk[x];
    		w[E]=MAXINT;
    		lnk[x]=E;
    	}
    	bool count(int y){
    		int x=y%Ha;
    		for(int j=lnk[x];j;j=nxt[j])
    		if(y==son[j])return true;
    		return false;
    	}
    	int& operator[](int y){
    		int x=y%Ha;
    		for(int j=lnk[x];j;j=nxt[j])
    			if(y==son[j])return w[j];
    		Add(x,y);
    		stk[++top]=x;
    		return w[E];
    	}
    }hs;
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int exgcd(int a,int b,int &x,int &y){
        if(!b){return x=1,y=0,a;}
        int re=exgcd(b,a%b,x,y),t=x;
        x=y;y=t-a/b*y;
        return re;
    }
    int fk(int a,int b,int p){
    	if(p==1)return 0;
        if(b==1)return a?0:-1;
        if(a%p==0)return b?-1:1;
        int Gcd,d=1,add=0;
    	while((Gcd=gcd(a,p))>1){
    		if(b%Gcd)return -1;
    		b/=Gcd,p/=Gcd,d=(d*a/Gcd)%p;
    		add++;
    	}
    	for(int i=0,fkk=1;i<add;i++,fkk=(fkk*a)%p)
    		if(fkk==b)return i;
    	int m=sqrt(p),bs=1;hs.clear();
    	for(int i=0;i<m;i++){
    		hs[bs]=min(hs[bs],i);
    		bs=(bs*a)%p;
    	}
    	for(int i=0;i<m;i++){
    		int x,y;
    		Gcd=exgcd(d,p,x,y);
    		x=(x*b%p+p)%p;
    		if(hs.count(x))return i*m+hs[x]+add;
    		d=(d*bs)%p;
    	}
        return -1;
    }
    signed main(){
    	int a,b,p,ans;
        while(1){
    		scanf("%lld%lld%lld",&a,&p,&b);
    		if(p==0)break;
            ans=fk(a,b,p);
            if(ans==-1)puts("No Solution");
            else printf("%lld
    ",ans);
        }
        return 0;
    }
    /*
    5 58 33
    2 4 3
    2 5 1
    2 5 2
    2 5 3
    2 5 4
    3 5 1
    3 5 2
    3 5 3
    3 5 4
    4 5 1
    4 5 2
    4 5 3
    4 5 4
    2 12345701 1111111
    65537 1111111121 1111111111
    0 0 0
    
    */
    
  • 相关阅读:
    根据模板查找目标控件
    DataGrid 通过行内容动态改变背景色
    Linq to XML
    数据库开发篇-基础篇
    序列化
    文件监控系统
    NewtonSoft JSON For Net
    java中如何把一个String类型的变量转换成double型的?
    在eclipse中查看某个方法被哪些类调用
    linux: su 无法设置用户ID: 资源暂时不可用
  • 原文地址:https://www.cnblogs.com/nlKOG/p/10879718.html
Copyright © 2011-2022 走看看