单位根反演学习笔记

1|0单位根反演

[n|a]=1nk=0n1wnak

证明:

i0(modn)时,由等比数列求和公式可得:

原式=1n×wnan1wna1,而右边分子为0,分母不为0,因此和为0。

i0(modn)时,有原式=1ni=0n1wn0=1

1|1qoj5370

j=0(ki+jn)

推式子:

j=0(ki+jn)=v=0k(kv)j=0n1(wnvi)jn=1nj=0n1wnijv=0k(kv)wnvj=1nj=0n1wnij(1+wnj)k

求出单位根就可以直接求了。

代码:

#include<bits/stdc++.h> using namespace std; int n,m,k,p,mod,P; int st[105],hst; inline int qpow(int x,int k){x%=mod;int ans=1;for(;k;k>>=1,x=1ll*x*x%mod)if(k&1)ans=1ll*ans*x%mod;return ans;} inline bool check(int x){ for(int i=1;i<=hst;i++){ if(qpow(x,P/st[i])==1)return 0; } return 1; } inline int getw(){ int s=sqrt(mod),x=mod-1; hst=0; for(int i=2;i<=s;i++)if(x%i==0){ st[++hst]=i; while(x%i==0)x/=i; } if(x>1)st[++hst]=x; for(int i=2;i<=mod;i++)if(check(i)){ return i; break; } return 0; } inline void solve(){ cin>>n>>p>>k>>m>>mod; m=((p-m)%n+n)%n; P=mod-1; int w=getw(); // cout<<w<<" "; w=qpow(w,P/n); // cout<<w<<endl; int inv=qpow(w,P-m),ans=0; for(int i=0,x=1,y=1;i<n;i++){ ans=(ans+1ll*y*qpow(1+x,k)%mod)%mod; y=1ll*y*inv%mod,x=1ll*x*w%mod; } ans=1ll*ans*qpow(n,mod-2)%mod; cout<<ans<<endl; } int main(){ ios::sync_with_stdio(false);cin.tie(0),cout.tie(0); int T; cin>>T; while(T--)solve(); return 0; }

__EOF__

本文作者Xttttr
本文链接https://www.cnblogs.com/Xttttr/p/18014370.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Xttttr  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示