P4720 exLucas TLE#9,11,12,23 求助
查看原帖
P4720 exLucas TLE#9,11,12,23 求助
263414
Sktic楼主2022/8/25 22:52

已经调试了两轮,修改了十几个错误,现在样例不会有死循环问题,然而交上去还会有四个点TLE(死循环)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
struct ask
{
	ll a,b;
}que[maxn];
ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b)
	{
		x=1;y=0;
		return a;
	}
	ll d=exgcd(b,a%b,x,y);
	ll t=x;
	x=y;
	y=t-(a/b)*y;
	return d;
}
ll inv(ll a,ll p)
{
	ll x,y;
	exgcd(a,p,x,y); 
	return (x%p+p)%p;
}
ll gcd(ll a,ll b)
{
	if(a<b)
		swap(a,b);
	return ((a%b==0)?b:gcd(b,a%b));
}
ll lcm(ll a,ll b)
{
	return a/gcd(a,b)*b;
}
ll CRT(ll n)
{
	ll m=1;
	for(int i=1;i<=n;i++)
		m*=que[i].a;
	long long int ans=0;
	for(int i=1;i<=n;i++)
	{
		ll mi=m/que[i].a,x,y;
		exgcd(mi,que[i].a,x,y);
		ans=(ans+que[i].b*mi*x%m+m)%m;
	}
	return ans;
}
ll exCRT(ll n)
{
	queue<ask> q;
	while(q.size()>1)
	{
		ll a1=q.front().a,b1=q.front().b;
		q.pop();
		ll a2=q.front().a,b2=q.front().b;
		q.pop();
		ll a=a1,b=a2,x,y;
		ll d=exgcd(a,b,x,y);
		ll t=a2/d;
		ll c=b2-b1;
		x=(x*c/d%t+t)%t;
		ll kp=a1*x+b1,kq=lcm(a1,a2);
		kp=(kp%kq+kq)%kq;
		q.push(ask{kq,kp});
	}
	return q.front().b%q.front().a;
}
ll qpow(ll x,ll p,ll mod)
{
	ll ans=1;
	while(p)
	{
		if(p&1)
			ans=(ans%mod*x%mod)%mod;
		x=(x%mod*x%mod)%mod;
		p>>=1;
	}
	return ans;
}
ll qqpow(ll x,ll p)
{
	ll ans=1;
	while(p)
	{
		if(p&1)
			ans=(ans*x);
		x=(x*x);
		p>>=1;
	}
	return ans;
}
ll qmul(ll x,ll p,ll mod)
{
	ll ans=0;
	while(p)
	{
		if(p&1)
			ans=(ans%mod+x%mod)%mod;
		x=(x%mod+x%mod)%mod;
		p>>=1;
	}
	return ans;
}
ll C(ll n,ll m,ll mod)
{
	if(m>n)
		return 0;
	m=((m>n-m)?(n-m):m);
	ll fz=1,fm=1; 
	for(ll i=0;i<m;i++)
	{
		fz=(fz*ll(n-i))%mod;
		fm=(fm*ll(i+1))%mod; 
	}
	return fz%mod*qpow(fm,mod-2,mod)%mod;
}
ll Lucas(ll n,ll m,ll mod)
{
	if(n<mod&&m<mod)
		return C(n,m,mod)%mod;
	return Lucas(n/mod,m/mod,mod)%mod*C(n%mod,m%mod,mod)%mod; 
}
ll timex(ll n,ll mod)
{
	return ((n<mod)?0:timex(n/mod,mod)+n/mod);
}
ll qfac(ll n,ll q,ll k,ll mod)
{
	if(!n)
		return 1;
	ll ans=1;
	for(int i=2;i<=mod;i++)
	{
		if(i%q!=0)
			ans=qmul(ans,i,mod)%mod;
	}
	ans=qpow(ans,n/mod,mod);
	for(int i=2;i<=n%mod;i++)
	{
		if(i%q!=0)
			ans=qmul(ans,i,mod)%mod;
	}
	ans=qmul(ans%mod,qfac(n/q,q,k,mod)%mod,mod)%mod;
	return ans%mod;
}
ll exC(ll n,ll m,ll pi,ll pk)
{
	ll mod=qqpow(pi,pk);
	ll a=qfac(n,pi,pk,mod),b=qfac(m,pi,pk,mod),c=qfac(n-m,pi,pk,mod);
	ll px=timex(n,pi)-timex(m,pi)-timex(n-m,pi);
	return a%mod*inv(b,mod)%mod*inv(c,mod)%mod*qpow(pi,px,mod)%mod;
}
ll exLucas(ll n,ll m,ll mod)
{
	ll ans=0,tmp=mod,tot=0;
	for(int i=2;i<=sqrt(mod)+5;i++)
	{
		if(tmp%i==0)
		{
			ll p=i,k=0;
			while(tmp%i==0)
				tmp/=i,k++;
			que[++tot].a=qqpow(p,k);que[tot].b=exC(n,m,i,k);
		}
	}
	if(tmp>1)
		que[++tot].a=tmp,que[tot].b=exC(n,m,tmp,1);
	return CRT(tot)%mod;
}
int main()
{
	ios::sync_with_stdio(false);
	ll n,m,mod;
	cin>>n>>m>>mod;
	cout<<exLucas(n,m,mod)<<endl;
	return 0;
}
2022/8/25 22:52
加载中...