exLucas WA 50pts求调
查看原帖
exLucas WA 50pts求调
172370
fzj2007楼主2021/10/21 14:03

RT,一直WA on test#10,13,16,17,19

题解第二篇枚举了 1m1\sim m 显然直接 101810^{18} 了,我用了两次 exlucas 求。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<iomanip>
#include<string>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<bitset>
using namespace std;
namespace IO{
    template<typename T>inline void read(T &x){
        x=0;
        char ch=getchar();
        bool flag=0;
        while(ch<'0'||ch>'9') flag=flag||(ch=='-'),ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+(ch^'0'),ch=getchar();
        if(ch!='.'){
            x=flag?-x:x;
            return;
        }
        double Base=0.1;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') x=x+Base*(ch^'0'),Base/=10.0,ch=getchar();
        x=flag?-x:x;
    }
    template<typename T>void prt(T x){
        if(x>9) prt(x/10);
        putchar(x%10+'0');
    }
    template<typename T>inline void put(char ch,T x){
        if(x<0) putchar('-'),x=-x;
        prt(x);
        putchar(ch);
    }
    const int DM[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
    inline void putd(char ch,double x,int w){
        if(x<0) putchar('-'),x=-x;
        if(!w){
            put(ch,(int)(x+0.5));
            return;
        }
        int prex=(int)x;
        x-=(int)x;
        x*=DM[w];
        x+=0.5;
        int nowx=(int)x,now=0;
        if(nowx>=DM[w]) nowx=0,prex++;
        put('.',prex);
        int xx=nowx;
        if(!xx) now=1;
        else while(xx) xx/=10,now++;
        now=w-now;
        while(now--) putchar('0');
        put(ch,nowx);
    }
    inline void putstr(string s){
        for(int i=0;i<s.length();i++) putchar(s[i]);
    }
}
using namespace IO;
#define ll long long 
inline ll power(ll x,ll y,ll p){//快速幂
	ll res=1;
	while(y){
		if(y&1) res=res*x%p;
		x=x*x%p;
		y>>=1;
	}
	return res;
}
inline ll exgcd(ll a,ll b,ll &x,ll &y){//扩欧
	if(!b) return a+(x=1)+(y=0)-1;
	ll d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}
inline ll inv(ll x,ll p){//求逆元
	ll a,b;
	exgcd(x,p,a,b);
	return (a%p+p)%p;
}
inline ll F(ll n,ll p,ll pk){//算n!/p^x mod p^k
	if(!n) return 1;
	ll lop=1,lst=1;
	for(ll i=1;i<=pk;i++)
		if(i%p) lop=lop*i%pk;
	lop=power(lop,n/pk,pk);
	for(ll i=(n/pk)*pk;i<=n;i++)
		if(i%p) lst=lst*(i%pk)%pk;
	ll res=lop*lst%pk*F(n/p,p,pk)%pk;
	return res;
}
inline ll getp(ll x,ll p){//计算多少个p
	if(x<p) return 0;
	return getp(x/p,p)+(x/p);
}
inline ll calc(ll n,ll m,ll p,ll pk,bool type){//计算C(n,m)/A(n,m)
	ll up=F(n,p,pk),down=inv(F(n-m,p,pk),pk);
	if(type) down=down*inv(F(m,p,pk),pk)%pk;//排列和组合
	ll nowp=power(p,getp(n,p)-getp(n-m,p)-(type?getp(m,p):0),pk);
	return nowp*up%pk*down%pk;
}
#define N 107
ll a[N],b[N],cnt;
inline ll CRT(ll n,ll M){
	ll ans=0;
	for(int i=1;i<=n;i++){
		ll nowm=M/a[i],invm=inv(nowm,a[i]);
		ans=(ans+b[i]*nowm%M*invm%M)%M;
	}
	return ans;
}
inline ll exlucas(ll n,ll m,ll p,bool type){
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	ll now=p;
	cnt=0;
	for(ll i=2;i*i<=p;i++){
		if(!(now%i)){
			ll pk=1;
			while(!(now%i)) now/=i,pk*=i;
			a[++cnt]=pk;
			b[cnt]=calc(n,m,i,pk,type);
		}
	}
	if(now!=1){
		a[++cnt]=now;
		b[cnt]=calc(n,m,now,now,type);
	}
	return CRT(cnt,p);
}
ll n,m,p,ans=1;
int main(){
	read(n),read(m),read(p);
	ans=exlucas(n,m,p,1)*exlucas(n,m,p,0)%p;
	put('\n',ans);
	return 0;
}
2021/10/21 14:03
加载中...