这一周做了组合数学和博弈方面的题目。组合数学方面比较熟悉,博弈方面比较难懂。
新学到了Lucas和Exlucas
lucas(模是质数)
l
u
c
a
s
(
x
,
y
)
=
C
(
x
%
p
,
y
%
p
)
∗
l
u
c
a
s
(
x
/
p
,
y
/
p
)
lucas(x,y)=C(x\%p,y\%p)*lucas(x/p,y/p)
lucas(x,y)=C(x%p,y%p)∗lucas(x/p,y/p)
Exlucas(模不一定是质数)
主要利用了唯一分解定理,中国剩余定理
下面是模板
ll fac(ll n,ll p,ll pk)//n!%pk
{
if(n==0)
return 1;
ll ans=1;
for(int i=1; i<pk; i++)//isp(p) (gcd(p,i)==1)==(p%i==1)
if(i%p)
ans=ans*i%pk;
ans=pows(ans,n/pk,pk);
for(int i=1; i<=n%pk; i++)//与p互质也是与pk互质
if(i%p)
ans=ans*i%pk;
ll test=fac(n/p,p,pk);
return ans*test%pk;
}
ll CRT(ll p,ll pk,ll mod)//中国剩余定理
{
return p%mod*res(mod/pk,pk)*(mod/pk)%mod;
}
ll C(ll m,ll n,ll p,ll pk)
{
if(m<n)return 0LL;
ll pm=fac(m,p,pk),pn=fac(n,p,pk),pc=fac(m-n,p,pk);
ll cnt=0;
for(ll i=p;i<=m;i*=p)
cnt+=m/i;
for(ll j=p;j<=n;j*=p)
cnt-=n/j;
for(ll k=p;k<=m-n;k*=p)//统计约去p的个数
cnt-=(m-n)/k;
return pm*res(pn,pk)%pk*res(pc,pk)%pk*pows(p,cnt,pk)%pk;
}
ll exlucas(ll m,ll n,ll mod)
{
int i=1;
ll rep=mod;
ll ans=0;
for(; rep>=pri[i]&&i<pri[0]; i++)
{
if(rep%pri[i]==0)
{
ll p=1;
while(rep%pri[i]==0)
{
p*=pri[i];
rep/=pri[i];
}
ans=(ans+CRT(C(m,n,pri[i],p),p,mod))%mod;
}
}
if(rep>1){
ans=(ans+CRT(C(m,n,rep,rep),rep,mod))%mod;
} return ans;
}
下一周,我决定结束数论方面的题目,复习一下数据结构方面的知识。