日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bsgs(Baby Steps Giant Steps)算法

發布時間:2023/12/10 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bsgs(Baby Steps Giant Steps)算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

BSGS算法(Baby Steps Giant Steps算法,大步小步算法,北上廣深算法,拔山蓋世算法)

適用問題

對于式子:

$$x^y=z(mod_p)$$

已知x,z,p,p為質數;

求解一個最小非負整數y;



存在一個y,屬于[0,p-2](費馬小定理)

于是有了一個笨拙的方法,枚舉y

枚舉y,期望效率:O(P)

尋求一種優化:

對式子變型:

設:$$y=i\sqrt{p}-j$$

則$$x^{i\sqrt{p}-j}=z(mod_p)$$

——這個變型的用意在于把y拆開

枚舉y,變成枚舉,i,j;

i在1~$\sqrt{p}$之間,j在0~$\sqrt{p}$之間

(根號上取整,其實i,j的范圍大可大些——只要保證y不會小于0)

枚舉(i,j),期望效率:$O(\sqrt{p}*\sqrt{}p)$

本質上沒有優化

接著變型:

$$x^{i\sqrt{p}}=z*x^{j}(mod_p)$$ 

——這個變型的用意在于真正把y分離為兩部分

枚舉j,把等號右邊的模后得數置于hash_table,此時同一個得數只留最大的j值;

從小到大枚舉i,計算等號左邊的模后得數,查詢hash_table,第一個成功查詢的i,與其相應的j,組成$i\sqrt{p}-j$即為最小的y,

期望效率:$O(\sqrt{p}*T(hash))$

效率優異,拔山蓋世的bsgs算法,就是這樣了;



?

例題:

[SDOI2011]計算器

代碼:

#include<cstring> #include<cstdio> #include<cmath> #define LL long long const int ss=999983; using namespace std; int hash_tab[1000000],tot; struct ss{int nu,next,j; }data[1000000]; void work(); void work1(); void work2(); void work3(); LL Sqr(LL ,int ); int hash(int, int ,int ); LL z,y,p; bool flag; int main() {work(); } void work(){int T,K;scanf("%d%d",&T,&K);while(T--){scanf("%lld%lld%lld",&y,&z,&p);if(K==1)work1();if(K==2)work2();if(K==3)work3();} } void work1(){int i,j,k;printf("%lld\n",Sqr(y,z)); } void work2(){int ans,less;if((!(y%p)&&z)||((y%p)&&!z)){printf("Orz, I cannot find x!\n");return;}printf("%lld\n",Sqr(y%p,p-2)*z%p); } void work3(){long long ysqrtp,sqrtp=ceil(sqrt(p));memset(hash_tab,0,sizeof(hash_tab));memset(data,0,sizeof(data));long long l=1,r=z%p;int i,j;if((!(y%p)&&z)||((y%p)&&!z)){printf("Orz, I cannot find x!\n");return;}ysqrtp=Sqr(y,sqrtp);for(i=0;i<=sqrtp;i++)hash(r,i,0),(r*=y)%=p;for(i=1;i<=sqrtp;i++){(l*=ysqrtp)%=p;if((j=hash(l,0,1))!=-1){printf("%lld\n",i*sqrtp-j);return ;}}printf("Orz, I cannot find x!\n"); } LL Sqr(LL x,int n){LL ret=1;while(n){if(n&1)(ret*=x)%=p;(x*=x)%=p;n>>=1;}return ret; } int hash(int num,int j,int flag){int tem;for(tem=hash_tab[num%ss];tem;tem=data[tem].next){if(data[tem].nu==num){if(!flag&&j>data[tem].j)data[tem].j=j;return data[tem].j;}if(!data[tem].next&&!flag){data[tem].next=++tot;data[tot].j=j;data[tot].nu=num;return -1;}}if(!flag){hash_tab[num%ss]=++tot;data[tot].j=j;data[tot].nu=num;}return -1; } View Code

?

轉載于:https://www.cnblogs.com/nietzsche-oier/p/7493671.html

總結

以上是生活随笔為你收集整理的bsgs(Baby Steps Giant Steps)算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。