目录
1.Luogu P2613【模板】有理数取余
2.POJ 1845Sumdiv
3.Luogu P2155沙拉公主的困惑(线性求逆)
一、【模板】有理数取余
题目:
求 a / b m o d 19260817 求a/bmod19260817 求a/bmod19260817
题解:
板子题没什么好说的
a
b
=
a
∗
i
n
v
(
b
)
\frac{a}{b}=a*inv(b)
ba=a∗inv(b)
输入太大,输的时候边读边取模就可以辣
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,mod=19260817;
inline ll read()
{
ll ans=0;char s=getchar();
while(s>'9'||s<'0')s=getchar();
while(s>='0'&&s<='9')
{
ans=((ans<<1)%mod+(ans<<3)%mod+(s&15))%mod;
s=getchar();
}return ans;
}
ll quick_m(ll i,ll n)
{
i%=mod;
ll ans=1,ds=i;
while(n)
{
if(n&1)
{
ans=ans*ds%mod;
}
ds=ds*ds%mod;
n>>=1;
}return ans%mod;
}
signed main(){
a=read();b=read();
if(b==0){printf("Angry!");return 0;}
printf("%lld",a*quick_m(b,mod-2)%mod);
return 0;
}
二、 Sumdiv
题目:
求 a b 的 约 数 和 m o d 9901 a^b的约数和mod \ 9901 ab的约数和mod 9901
题解:
若a的唯一质因数分解为
a
=
p
1
k
1
p
2
k
2
p
3
k
3
.
.
.
p
n
k
n
a=p_1^{k_1}p_2^{k_2}p_3^{k_3}...p_n^{k_n}
a=p1k1p2k2p3k3...pnkn
则
a
b
a^b
ab的唯一质因数分解为
a
b
=
p
1
k
1
b
p
2
k
2
b
p
3
k
3
b
.
.
.
p
n
k
n
b
a^b=p_1^{k_1b}p_2^{k_2b}p_3^{k_3b}...p_n^{k_nb}
ab=p1k1bp2k2bp3k3b...pnknb
约数和数学表达
s
=
(
1
+
p
1
+
p
1
2
.
.
.
+
p
1
k
1
b
)
(
1
+
p
2
+
p
2
2
.
.
.
+
p
2
k
2
b
)
.
.
.
(
1
+
p
n
+
p
n
2
.
.
.
+
p
n
k
n
b
)
s=(1+p_1+p_1^2...+p_1^{k_1b})(1+p_2+p_2^2...+p_2^{k_2b})...(1+p_n+p_n^2...+p_n^{k_nb})
s=(1+p1+p12...+p1k1b)(1+p2+p22...+p2k2b)...(1+pn+pn2...+pnknb)
等比数列求解
s
=
(
p
1
k
1
b
+
1
−
1
p
1
−
1
)
(
p
2
k
2
b
+
1
−
1
p
2
−
1
)
.
.
.
(
p
n
k
n
b
+
1
−
1
p
n
−
1
)
s=(\frac{p_1^{k_1b+1}-1}{p_1-1})(\frac{p_2^{k_2b+1}-1}{p_2-1})...(\frac{p_n^{k_nb+1}-1}{p_n-1})
s=(p1−1p1k1b+1−1)(p2−1p2k2b+1−1)...(pn−1pnknb+1−1)
我们逆元+快速幂?
不,
p
i
−
1
可
能
为
9901
的
倍
数
,
不
与
9901
互
质
,
此
时
没
有
逆
元
pi-1可能为9901的倍数,不与9901互质,此时没有逆元
pi−1可能为9901的倍数,不与9901互质,此时没有逆元
那怎么办?
这里有个非常nice 的idea,上图
若
求
a
b
(
m
o
d
p
)
,
且
刚
好
有
a
为
b
的
倍
数
若求\frac a b (mod \ p ),且刚好有a为b的倍数
若求ba(mod p),且刚好有a为b的倍数
注意:有多组数据。。。还有快速幂时可能会爆long long,用龟速乘。
卡在RE的应该不止我一个吧(现已解决,a>1卡了几乎两页)
#include<iostream>
#include<string.h>
#include<stdio.h>
#define ll long long
using namespace std;
ll qk_c(ll a,ll b,ll mod)
{
ll ans=0;a%=mod;
while(b)
{
if(b&1)
{
ans=(ans+a)%mod;
}
a=(a+a)%mod;
b>>=1;
}
return ans;
}
ll qk_m(ll a,ll k,ll mod)
{
ll ans=1;a%=mod;
while(k)
{
if(k&1)
{
ans=qk_c(ans,a,mod);
}
a=qk_c(a,a,mod);
k>>=1;
}
return ans;
}
const int N=10005;
int z[N],p;
bool vis[N];
void init()
{
for(int i=2;i<N;i++)
{
if(!vis[i])z[++p]=i;
for(int j=1;j<=p&&i*z[j]<N;j++)
{
vis[i*z[j]]=1;
if(i%z[j]==0)break;
}
}
}
const int mod=9901;
ll a,b,ans;
int k;
int main()
{
init();
while(cin>>a>>b)
{
ans=1;
for(int i=1;i<=p&&z[i]*z[i]<=a;i++)
{
if(a%z[i]==0)
{
k=0;while(a%z[i]==0)a/=z[i],k++;
ll M=mod*(z[i]-1);
ans*=(qk_m(z[i],k*b+1,M)+M-1)/(z[i]-1);
ans%=mod;
}
}
if(a>1)
{
ll M=mod*(a-1);
ans*=(qk_m(a,b+1,M)+M-1)/(a-1);
ans%=mod;
}
cout<<ans<<endl;
}
return 0;
}
三、沙拉公主的困惑
题目:
求 1 − > N ! 1->N! 1−>N!中与 M ! M! M!互质的个数
题解:
推演一下,最后得
N
!
M
!
ϕ
(
M
!
)
\frac {N!}{M!} \phi{(M!)}
M!N!ϕ(M!)
=>
N
!
(
1
−
p
1
p
1
)
(
1
−
p
2
p
2
)
.
.
.
(
1
−
p
k
p
k
)
N!(\frac {1-p_1}{p_1})(\frac {1-p_2}{p_2})...(\frac {1-p_k}{p_k})
N!(p11−p1)(p21−p2)...(pk1−pk)
一堆预处理,质数+线性求逆+阶乘。。。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read()
{
ll ans=0;char s=getchar();
while(!isdigit(s))s=getchar();
while(isdigit(s))
{
ans=(ans*10)+(s&15);
s=getchar();
}return ans;
}
const int N=1e7+10;
int T;
ll n,m,mod;
int z[N],p;
bool vis[N];
void get_prime()
{
for(int i=2;i<N;i++)
{
if(!vis[i])z[++p]=i;
for(int j=1;j<=p&&i*z[j]<N;j++)
{
vis[i*z[j]]=1;
if(i%z[j]==0)break;
}
}
}
ll inv[N],mul[N],pt[N];
int main()
{
scanf("%d%lld",&T,&mod);
get_prime();
inv[1]=1;inv[0]=1;
for(int i=2;i<N;i++)
inv[i]=inv[mod%i]*(mod-mod/i)%mod;
mul[1]=1;
for(int i=2;i<N;i++)
mul[i]=mul[i-1]*i%mod;
pt[1]=1;
for(int i=2;i<N;i++)
if(!vis[i])
pt[i]=pt[i-1]*(i-1)%mod*inv[i%mod]%mod;
else pt[i]=pt[i-1];
while(T--)
{
n=read();m=read();
printf("%lld\n",mul[n]*pt[m]%mod);
}
}//假装没开O2就过了