模板——EXBSGS-程序员宅基地

\(hash\)版,省时间耗空间

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long LL;
const LL N=40000,Max=(1<<16)-1;
bool bk;
LL X,Z,K,len;
bool vis[70000];
struct node{
    LL d,id,next;
}hash[2*Max];

int exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0) {x=1,y=0;return a;}
    LL tx,ty;
    LL d=exgcd(b,a%b,tx,ty);
    x=ty;y=tx-(a/b)*ty;
    return d;
}

void ins(LL d,LL id)
{
    LL t=d&Max;
    if(!vis[t]) {
        vis[t]=1;
        hash[t].d=d,hash[t].id=id,hash[t].next=-1;
        return ;
    }
    for(;hash[t].next!=-1;t=hash[t].next)
    {
        if(hash[t].d==d) return;
    }
    hash[t].next=++len;
    hash[len].d=d;hash[len].id=id;hash[len].next=-1;
}

LL find(LL d)
{
    LL t=d&Max;
    if(!vis[t]) return -1;
    for(;t!=-1;t=hash[t].next)
    {
        if(hash[t].d==d) return hash[t].id;
    }
    return -1;
}

LL BSGS()
{
    LL t,g,x,y,pm,a,b,c,m,k,sum,am;
    a=X;b=K;c=Z;k=1;sum=0;t=1%c;
    for(int i=0;i<=100;i++){
        if(t==b) return i;
        t=t*a%c;
    }
    while((g=exgcd(X,c,x,y))!=1)
    {
        k=(k*X/g)%c;
        c/=g;
        if(b%g) return -1;
        b/=g;
        sum++;
    }
    m=(LL)(ceil((double)sqrt((double)c)));
    ins(k,0);
    t=k;pm=1;
    for(int i=1;i<=m;i++)
    {
        t=t*a%c,pm=pm*a%c;
        ins(t,i);
    }        
    exgcd(pm,c,x,y);
    am=x%c+c;
    t=b;
    for(int i=0;i<=m;i++)
    {
        x=find(t);
        if(x!=-1) return i*m+x+sum;
        t=t*am%c;
    }
    return -1;
}

int main()
{
    while(~scanf("%lld%lld%lld",&Z,&X,&K)){
        K%=Z;len=Max;
        memset(vis,0,sizeof(vis));
        LL ans=BSGS();
        if(ans!=-1) printf("%lld\n",ans);
        else printf("no solution!\n");
    }
    return 0;
}

二分版,耗时间省空间

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long LL;
const int N=40000;
bool bk;
LL X,Z,K,a,b,c,m,k,sum,am,bl;
struct node{
    LL d,id;
}bit[N],p[N];

bool cmp(node x,node y){
    if(x.d!=y.d) return x.d<y.d;
    return x.id<y.id;
}

LL gcd(LL u,LL v)
{
    if(v==0) return u;
    return gcd(v,u%v);
}

LL find(LL x)
{
    int l=0,r=bl;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(bit[mid].d==x) return bit[mid].id;
        if(bit[mid].d>x) r=mid-1;
        if(bit[mid].d<x) l=mid+1;
    }
    return -1;
}

void exgcd(LL u,LL v,LL &x,LL &y)
{
    if(v==0) {x=1,y=0;return ;}
    LL tx,ty;
    exgcd(v,u%v,tx,ty);
    x=ty;y=tx-(u/v)*ty;
    return;
}

LL BSGS()
{
    LL t,g,x,y,pm;
    a=X;b=K;c=Z;k=1;sum=0;bk=1;bl=0;t=1%c;
    for(int i=0;i<=100;i++){//避免a的负数次方
        if(t==b) return i;
        t=t*a%c;
    }
    while((g=gcd(X,c))!=1)
    {
        k=(k*X/g)%c;//k记得要mod,否则溢出
        c/=g;
        if(b%g) return -1;
        b/=g;
        sum++;
    }
    m=(LL)(ceil((double)sqrt((double)c)));//要约分之后再求m
    p[0].d=k%c;
    p[0].id=0;
    pm=1;//pm是不用*k的
    for(int i=1;i<=m;i++) 
        p[i].d=p[i-1].d*a%c,pm=pm*a%c,p[i].id=i;
    sort(p,p+1+m,cmp);
    bit[0]=p[0];bl=0;
    for(int i=1;i<=m;i++)
    {
        if(p[i].d!=p[i-1].d) bit[++bl]=p[i];
    }
    exgcd(pm,c,x,y);
    am=(x%c+c);//避免am=0
    
    t=b;
    x=find(b);
    if(x!=-1) return x;
    for(int i=1;i<=bl;i++)
    {
        t*=am;t%=c;
        x=find(t);
        if(x!=-1)
            return i*m+x;
    }
    return -1;
}

int main()
{
//     freopen("exbsgs10.in","r",stdin);
//     freopen("exbsgs10.out","w",stdout);
    while(~scanf("%lld%lld%lld",&Z,&X,&K)){
        if(!X && !Z && !K) return 0;
        K%=Z;
        LL ans=BSGS();
        if(ans!=-1) printf("%lld\n",ans+sum);
        else printf("no solution!\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/lajioj/p/9529255.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aihuai9945/article/details/101141147

智能推荐

BASE64、MD5、SHA、HMAC几种加密算法-程序员宅基地

文章浏览阅读106次。BASE64编码算法不算是真正的加密算法。 MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 BASE64 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The ..._base 64编码 和mad5 和雪花算法

住宅IP、家庭宽带IP以及原生IP,它们有什么区别?谷歌开发者账号应选择哪种IP?-程序员宅基地

文章浏览阅读1.1k次。IP地址(Internet Protocol Address)是互联网协议地址的简称,是互联网通信的基础,互联网上每一个网络设备的唯一标识符每个在线的设备都需要一个IP地址,这样才能在网络中找到它们并进行数据交换。IP地址有很多种类型,今天跟大家简单分享一下住宅IP、家庭宽带IP以及原生IP的区别。住宅IP通常是指由互联网服务提供商(ISP)分配给家庭的或小型办公室使用的互联网连接IP地址,并可能随着网络连接的变化而变化。此类IP地址主要用于日常网络活动,如浏览网页、发送接收电子邮件、上网冲浪等。

如何更改layui form表单位置,宽度,颜色等_layui-form-item 宽度-程序员宅基地

文章浏览阅读2.6w次,点赞14次,收藏30次。如何更改layui form表单位置,宽度,颜色等_layui-form-item 宽度

【翻译】Efficient Data Loader for Fast Sampling-Based GNN Training on Large Graphs_pagraph: scaling gnn training on large graphs via -程序员宅基地

文章浏览阅读612次。写的非常好_pagraph: scaling gnn training on large graphs via computation-aware caching

炫酷的HTML代码-程序员宅基地

文章浏览阅读2.7w次,点赞61次,收藏285次。很炫酷的html代码:<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>star</title><script type="text/javascript">window.onload = function () {C = Math.cos; // cache Math objectsS = Math.si.._炫酷的html

【HDU - 1166】敌兵布阵 (线段树模板 单点更新+ 区间查询)-程序员宅基地

文章浏览阅读204次。题干:C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。 中央情报局要研究敌人究竟演习什...

随便推点

【免费题库】华为OD机试C卷 - 数字字符串组合倒序(Java 代码+解析)-程序员宅基地

文章浏览阅读2.3k次。题目描述对数字,字符,数字串,字符串,以及数字与字符串组合进行倒序排列。字符范围:由 a 到 z, A 到 Z,数字范围:由 0 到 9符号的定义:“-”作为连接符使用时作为字符串的一部分,例如“20-years”作为一个整体字符串呈现;连续出现 2 个 “-” 及以上时视为字符串间隔符,如“out--standing”中的”–“视为间隔符,是 2 个独立整体字符串”out”和”standing”;除了 1,2 里面定义的字符以外其他的所有字符,都是非法字符,作为字符串的间隔符处理,倒序后

Android(14) ArrayAdapter(数组适配器)的三种方法-程序员宅基地

文章浏览阅读5w次,点赞36次,收藏138次。ArrayAdapter数组适配器用于绑定格式单一的数据,数据源可以是集合或者数组列表视图(ListView)以垂直的形式列出需要显示的列表项。实现过程:新建适配器->添加数据源到适配器->视图加载适配器第一种:直接用ListView组件创建列表每一行只有一行文字效果如图:activity_list布局:<?xml version="1.0" e..._arrayadapter

助力商家健康经营 创业者为水滴直播点赞-程序员宅基地

文章浏览阅读43次。近日,水滴直播平台登上了舆论的风口浪尖。有人认为水滴直播涉嫌侵犯隐私,但也有人表示这种互联网新生事物可以有效规避很多风险,值得鼓励,不应一棒子打死。记者采访时发现,很多商家、创业者对于水滴直播纷纷表示支持,并直言水滴直播为他们的经营带来了很大帮助。 邹志泉在北京丰台区经营着一家批发厂家直销男女内衣裤的店铺,平时就打开水滴直播,分享他在店铺的经营画面。面对水滴直播涉及隐私的提问,邹志泉明确表...

java毕业设计宠物收养管理系统Mybatis+系统+数据库+调试部署-程序员宅基地

文章浏览阅读67次。springboot基于SpringBoot的电影社区网站。springboot基于springboot食品销售网站。ssm基于微信平台的校园汉服租赁系统的设计与实现。ssm基于SSM高校教师个人主页网站的设计与实现。ssm基于SSM框架的在线健康系统设计与实现。ssm基于HTML的武昌理工学院二手交易网站。ssm基于JavaEE的网上图书分享系统。ssm基于Javaee的项目任务跟踪系统。

Nginx使用之反向代理、负载均衡、动静分离教程。_php动静分离-程序员宅基地

文章浏览阅读61次。负载均衡是指将客户端的请求分发到多个后端服务器,以平衡服务器的负载。反向代理是指将客户端的请求转发到后端服务器,并将响应返回给客户端。通过配置反向代理,Nginx将转发所有来自客户端的请求到后端服务器,并将响应返回给客户端。通过这样的配置,Nginx将根据请求的URL路径选择是将请求转发到后端服务器还是直接返回静态资源文件。通过配置负载均衡,Nginx将按照指定的策略将客户端的请求分发到后端服务器上,从而实现负载均衡。配置反向代理:编辑Nginx配置文件(通常是nginx.conf),在。_php动静分离

HTML5有哪些新特性_谈谈html5的一些新特性-程序员宅基地

文章浏览阅读9.5k次,点赞3次,收藏18次。(一) 语义标签(二)增强型表单(三)视频和音频(四)Canvas绘图(五)SVG绘图(六)地理定位(七)拖放API(八) WebWorker(九) WebStorage(十)Web..._谈谈html5的一些新特性

推荐文章

热门文章

相关标签