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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【模板篇】数论大杂烩~

發(fā)布時(shí)間:2024/9/5 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【模板篇】数论大杂烩~ 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

離省選已經(jīng)不剩幾天了, 然而自己還是啥也不會(huì), 所以就臨陣磨槍刷一刷板子, 萬(wàn)一用上了就賺到了~~
這一篇就寫(xiě)寫(xiě)數(shù)論?(希望只考到自己打的板子然而這是不可能的←_←

盡量不壓行吧, 能寫(xiě)得好懂點(diǎn)就寫(xiě)得好懂一點(diǎn)吧... (為了省事就全開(kāi)long long了哈, 卡常題請(qǐng)謹(jǐn)慎復(fù)制...)
里面枚舉的內(nèi)容可能沒(méi)啥規(guī)律, 想起啥寫(xiě)啥, 應(yīng)該會(huì)很亂...

先是應(yīng)該是不用寫(xiě)的gcd:

LL gcd(LL a,LL b){if(!b) return a;return gcd(b,a%b); }

然后是exgcd:

void exgcd(LL a,LL b,LL &x,LL &y){if(!b) x=1,y=0;else exgcd(b,a%b,y,x),y-=(a/b)*x; }

快速冪也是炒雞常用的:

LL qpow(LL a,LL b,LL p,LL s=1){for(;b;b>>=1,a=a*a%p)if(b&1) s=s*a%p;return s; }

然后是跟質(zhì)數(shù)或者辣雞反演有關(guān)的題里幾乎都要用到的線篩(這玩意我還日常打不對(duì)的說(shuō)...)
篩質(zhì)數(shù)的同時(shí)寫(xiě)一下篩\(\mu, \varphi, \sigma_0,\sigma_1\)這些函數(shù)(打表找規(guī)律的積性函數(shù)就不寫(xiě)了也寫(xiě)不完)

/* pr質(zhì)數(shù)數(shù)組 tot質(zhì)數(shù)個(gè)數(shù) mu莫比烏斯函數(shù) phi歐拉函數(shù) d約數(shù)個(gè)數(shù) sd約數(shù)和 fd 篩約數(shù)個(gè)數(shù)用的輔助數(shù)組(最小質(zhì)因子的個(gè)數(shù)) fsd 篩約數(shù)和用的輔助數(shù)組 (最小質(zhì)因子等比數(shù)列的前綴和,即 (1+p1+p1^2+p1^3+...+p1^k1)) */ void shai(){np[1]=mu[1]=phi[1]=d[1]=sd[1]=1;for(int i=2,k;i<=n;++i){if(!np[i]){pr[++tot]=i; mu[i]=-1; phi[i]=i-1;fd[i]=1; d[i]=2; fsd[i]=sd[i]=i+1;}for(int j=1;j<=tot&&(k=i*pr[j])<=n;++j){ np[k]=1;if(i%pr[j]==0){mu[k]=0; phi[k]=phi[i]*pr[j];fd[k]=fd[i]+1; d[k]=d[i]/(fd[i]+1)*(fd[i]+2);fsd[k]=fd[i]*pr[j]+1;sd[k]=sd[i]/fsd[i]*fsd[k];break;}mu[k]=-mu[i]; phi[k]=phi[i]*(pr[j]-1);fd[k]=1; d[k]=d[i]*2; fsd[k]=pr[j]+1;sd[k]=sd[i]*sd[pr[j]];}} }

Emmmm寫(xiě)個(gè)線篩寫(xiě)了好久最后果然還是出錯(cuò)了..

逆元相關(guān):
然后是兩種求\(a\)\(mod\ p\)逆元的方法:

// 費(fèi)馬小定理的a^p-2代碼就不寫(xiě)了_(:з」∠)_ // 另一種就是利用exgcd: LL inv(LL a,LL p){if(!a) return 0;LL x,y; exgcd(a,p,x,y);return (x+p)%p; }

線性求出所有逆元:

inv[1]=1; for(int i=2;i<p;++i)inv[i]=(p-(p/i))*inv[p%i]%p;

O(1)快速乘(損精度):

LL multi(Ll a,LL b){return (a*b-(LL)((long double)a*b/p)*p+p)%p; }

然后是一發(fā)Lucas定理:

// 這里默認(rèn)階乘和階乘逆元已經(jīng)預(yù)處理好分別放在fac和inv數(shù)組里了~ LL lucas(LL n,LL m,LL p){if(n<m) return 0;if(n<p) return fac[x]*inv[y]*inv[x-y];return lucas(n/p,m/p,p)*lucas(n%p,m%p,p); }

再來(lái)一波CRT(中國(guó)剩余定理)

//假設(shè)模數(shù)存在p數(shù)組里, 余數(shù)存在c數(shù)組里, 一共有n個(gè)式子, 模數(shù)的總乘積是P. void CRT(LL ans=0){for(int i=0;i<n;++i)ans=(ans+c[i]*(P/p[i])%P*inv(P/p[i],p[i])%P)%P;return ans; }

突然發(fā)現(xiàn)自己還沒(méi)寫(xiě)過(guò)擴(kuò)展CRT哇, 趕緊新寫(xiě)一發(fā)~

int exCRT(){for(int i=2;i<=n;++i){p1=p[i-1],p2=p[i],c1=c[i-1],c2=c[i];g=gcd(p1,p2);if((c2-c1)%g) return -1;p[i]=p1*p2/t;c[i]=inv(p1/t,p2/t)*((c2-c1)/t)%(p2/t)*p1+c1;c[i]=(c[i]%p[i]+p[i])%p[i];}return c[n]; }

然后寫(xiě)一發(fā)bsgs~叫拔山蓋世的都是邪教!北上廣深才是王道!

map<LL,int> mmp; LL BSGS(LL y,LL z,LL p){ mmp.clear();LL m=sqrt(p)+1; po=qpow(y,m,p);for(LL j=0;j<=m;++j){v[z]=j; z=z*y%c;} z=1;for(LL i=1;i<=m;++i){z=z*po%p;if(v[x]) return i*m-v[x];}return -1; }

然后就是組合數(shù)題的boss了(僅代表個(gè)人觀點(diǎn)), 非常神的 擴(kuò)展Lucas~~~~
去年這時(shí)候?qū)W的, 現(xiàn)在幾乎忘得一干二凈
剛才打了一遍板子, 然而還是沒(méi)有背過(guò)...

LL mul(LL n,LL pi,LL pk){if(!n) return 1; LL ans=1;if(n/pk){for(LL i=2;i<=pk;++i)if(i%pi) ans=ans*i%pk;ans=qpow(ans,n/pk,pk);}for(LL i=2;i<=n%pk;++i)if(i%pi) ans=ans*i%pk;return ans*mul(n/pi,pi,pk)%pk; } LL C(LL n,LL m,LL p,LL pi,LL pk){if(m>n) return 0;LL a=mul(n,pi,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk),k=0,ans;for(LL i=n;i;i/=pi) k+=i/pi;for(LL i=m;i;i/=pi) k-=i/pi;for(LL i=n-m;i;i/=pi) k-=i/pi;ans=a*inv(b,pk)%pk*inv(c,pk)%pk*qpow(pi,k,pk)%pk;return ans*(p/pk)%p*inv(p/pk,pk)%p; } int main(){LL n,m,p,ans=0; scanf("%lld%lld%lld",&n,&m,&p); n+=m;for(LL x=p,i=2;i<=p;++i)if(x%i==0){LL pk=1;while(x%i==0) pk*=i,x/=i;ans=(ans+::C(n, m, p, i, pk))%p;}printf("%lld\n",ans); }

再來(lái)補(bǔ)充一些反演相關(guān):
最基本的枚舉除法

for(int i=1,last;i<=n;i=last+1){last=n/(n/i);// 然后處理的是關(guān)于last和i-1的式子..(一般就是前綴和相減..) }

公式就記這幾個(gè)其他常見(jiàn)的都可以推...
\[ \mu*1=\epsilon \\ \varphi*1=n \\ id_k*1=\sigma_k \]

套路性的東西:
\[ \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1]=\sum_{d=1}^n\mu(d)\left\lfloor\frac nd\right\rfloor\left\lfloor\frac md\right\rfloor \\ \sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)=1]=2*\sum_{d=1}^n\varphi(d)-1 \]

杜教篩的模板(舒老師說(shuō)這玩意卵用沒(méi)有但我覺(jué)得很有用噠(肯定是我太弱了)):
\[ 要求出f(x)的前綴和s_f(x), 我們要找到一個(gè)合適的函數(shù)g(x), 滿足g(x)和(f*g)(x)的前綴和都易求(一般是要求O(1)). \\ 令s_{f*g}(x)表示(f*g)x的前綴和, 那么有: \\ s_f(x)=\frac{s_{f*g}(x)-\sum_{i=2}^ns_f(\left\lfloor\frac ni\right\rfloor)g(i)}{g(1)} (當(dāng)然正常來(lái)說(shuō)g(1)=1就不用除辣)\\ 然后我們枚舉除法對(duì)上式整除分塊遞歸處理s_f(\left\lfloor\frac ni\right\rfloor)這個(gè)部分就可以了~ \]

于是附上幾個(gè)常見(jiàn)的易求前綴和的函數(shù)的求和公式:
\[ \sum_{i=1}^n1(i)=n \\ \sum_{i=1}^n\epsilon(i)=1 \\ \sum_{i=1}^nid(i)=\frac{n(n+1)}2 \\ \sum_{i=1}^nid_2(i)=\frac{n(n+1)(2n+1)}6 \\ \sum_{i=1}^nid_3(i)=(\frac{n(n+1)}2)^2 \]

然后就是一些注意事項(xiàng):

  • \(10^{10}\)范圍杜教篩篩\(O(n^\frac 23)\)大約是\(4.7*10^6\), 所以500W一般可以, 不過(guò)空間允許的話再篩大一點(diǎn)在1e7左右會(huì)更好~
  • \(10^{10}*{10^9+7}\)有幾率會(huì)爆long long, 雖然情況比較少但我相信足夠毒瘤的出題人是可以有足夠的時(shí)間和耐心搞出來(lái)hack數(shù)據(jù)的..., 所以保險(xiǎn)起見(jiàn)要開(kāi)unsigned long long...
  • long long計(jì)算非常慢, 能用int的地方盡量用int, 當(dāng)然那就要注意強(qiáng)轉(zhuǎn)long long步步取模(少一個(gè)都有可能炸←_←)的問(wèn)題了~
  • 枚舉因子的時(shí)候最好把設(shè)\(i=td\)寫(xiě)出來(lái)防止把應(yīng)該化的\(t\)丟掉(可以適當(dāng)找下規(guī)律驗(yàn)證化的式子對(duì)否)..
  • 大約就這樣吧, 說(shuō)太多自己也是記不住的...

轉(zhuǎn)載于:https://www.cnblogs.com/enzymii/p/8697113.html

總結(jié)

以上是生活随笔為你收集整理的【模板篇】数论大杂烩~的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。