G. 小花梨的函数
2019-05-19 16:30 一只弱鸡丶 阅读(257) 评论(0) 编辑 收藏 举报#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define ll long long #define re register inline void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } const int M=2e7+10; int F[M]; bool vis[100005]; int pri[100005],mu[100005],p; inline void init(int n) { mu[1]=1; int cnt=0; for(re int i=2;i<=n;i++) { if(!vis[i]) pri[++cnt]=i,mu[i]=-1; for(re int j=1;j<=cnt&&i*pri[j]<=n;j++) { vis[i*pri[j]]=1; if(i%pri[j]==0) break; mu[i*pri[j]]=-mu[i]; } } for(re int i=1;i<=n;i++) mu[i]+=mu[i-1]; } ll solve(int n,int m) { ll ans=0; for(int l=1,r;l<=n;l=r+1) { r=min(n/(n/l),m/(m/l)); ans+=1ll*(n/l)*(m/l)*(mu[r]-mu[l-1]); } return ans; } int main() { int cnt,n,m,a; read(n); read(m); read(a); read(p); F[1]=F[2]=1; for(re int i=3;i<=M;i++) { F[i]=(F[i-1]+F[i-2])%p; if(F[i]==1&&F[i-1]==1) { cnt=i-2; break; } } if(n>m) swap(n,m); init(n); ll ans=0; int now=1; for(re int i=1;i<=n;i++) { now=1ll*now*a%cnt; ans=(ans+(solve(n/i,m/i)%p)*F[(now+cnt-1)%cnt]%p)%p; } printf("%lld",ans); return 0; }