社区讨论

ub exlucas

P4720【模板】扩展卢卡斯定理 / exLucas参与者 4已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@lo39lfg1
此快照首次捕获于
2023/10/24 03:02
2 年前
此快照最后确认于
2023/10/24 03:02
2 年前
查看原帖
没开 O2 就能过,开了就寄,不清楚哪里 ub 了,写得很乱(有无帮忙看看的或者有啥东西能辅助查 ub 的吗。
CPP
#include <bits/stdc++.h>
#define int __int128
#define pb push_back
//#define
using namespace std;
int rd() {
	int f=1,sum=0; char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
	return sum*f;
}
void pr(int x) {
	static int st[10000]; int tot=0;
	if(x<0) {
		putchar('-'); x=-x;
	}
	if(x==0) {
		putchar('0'); return ;
	}
	while(x) st[++tot]=x%10,x/=10;
	for(int i=tot;i>=1;i--) putchar(st[i]+'0');
}
int n,m,P,pp[10000],A[10000],M[100000],t,mod,p,CT;

int fpow(int x,int y) {
	int res=1; x%=mod;
	while(y) {
		if(y&1) res=res*x%mod;
		y>>=1; x=x*x%mod;
	} return res;
}
int jie[5000005];
int sol(int n) {
	if(!n) return 1;
	if(n==1) return 1;
	int qwq=n/mod,res=sol(n/p);
//	pr(mod); putchar(' '); pr(n); putchar('\n');
	res=res*fpow(jie[mod],qwq)%mod;
//	cout<<n<<" "<<mod<<'\n';
//	for(int i=1;i<=n;i++) {
//		if(i%p) res=res*i%mod;
//	}
	for(int i=qwq*mod+1;i<=n;i++) {
		if(i%p) res=res*i%mod;
	}
//	for(int i=1;i<=n;i++) {
//		if(__gcd(i,p)==1) res=res*i%mod; 
//	}
	return res;
//	int res=1;
//	for(int i=1;i<=n;i++) {
//		int x=i;
//		while(__gcd(x,p)!=1) x/=p;
//		res=res*x%mod;
//	}return res;
}

int vp(int n) {
	int res=0;
	for(int i=p;;i*=p) {
//		pr(p); putchar('\n');
		if((n/i)==0) break ;
		res+=n/i;
	} return res;
}

//int baoli(int x) {
//	int res=1;
//	if(m<p) {	
//		for(int i=n-m+1;i<=n;i++) res=res*i%mod;
//		for(int i=1;i<=m;i++) res=res*fpow(i,mod-2)%mod;
//		return res; 
//	}
//	for(int i=m+1;i<=n;i++) res=res*i%mod;
//	for(int i=1;i<=n-m;i++) res=res*fpow(i,mod-2)%mod;
//	return res;
//}

pair<int,int>exgcd(int a,int b) {
	if(!b) {
		return make_pair(1,0);
	}
	auto qwq=exgcd(b,a%b);
	return make_pair(qwq.second,qwq.first-(a/b)*qwq.second);
}

int lcm(int x,int y) {
	return x/__gcd(x,y)*y;
}

int inv(int a) {
	auto qwq=exgcd(a,mod);
	return (qwq.first%mod+mod)%mod;
}

int get(int x) {
	mod=M[x]; p=pp[x]; jie[0]=1;
	for(int i=1;i<=mod;i++) {
		jie[i]=jie[i-1];
		if(i%p!=0) jie[i]=jie[i]*i%mod;
	}
//	if(n<p||m<p||n-m<p) {
//		return baoli(x);
//	}
	int res=vp(n)-vp(m)-vp(n-m);
	res=fpow(p,res);
	res=res*sol(n)%mod*inv(sol(n-m))%mod*inv(sol(m))%mod;
//	cout<<res<<" "<<baoli(x)<<'\n';
//	cout<<p<<" "<<mod<<" "<<res<<" "<<vp(n)-vp(m)-vp(n-m)<<'\n';
	return res;
}

signed main() {
//	cin.tie(0); ios::sync_with_stdio(false);
	n=rd(); m=rd(); P=rd();
	if(m>n) {
		cout<<"0"; return 0;
	}
	for(int i=2;i*i<=P;i++) {
		if(P%i) continue ;
		M[++t]=1; pp[t]=i;
		while(P%i==0) M[t]*=i,P/=i;
	}
	if(P!=1) M[++t]=P,pp[t]=P;
	for(int i=1;i<=t;i++) {
		if(M[i]==0) {
			cout<<"wa";
		}
	}
	for(int i=1;i<=t;i++) A[i]=get(i);
	if(t==1) {
		A[1]=(A[1]%M[1]+M[1])%M[1];
		pr(A[1]); return 0;
	}
	int ans=A[1],MM=M[1];
	for(int i=2;i<=t;i++) {
//		cout<<A[i]<<'\n';
		int a=MM,b=M[i],C=(A[i]-ans%b+b)%b;
		int d=__gcd(a,b);
//		if(C%d) {
//			fl=0; break ;
//		}
		auto qwq=exgcd(MM,M[i]);
		int x=qwq.first;
		if(d==0) {
			cout<<"WA";
		}
		x=x*(C/d)%(M[i]/d);
		int q=lcm(MM,b);
		ans=(ans+x*MM%q)%q;
//		
		MM=q;ans=(ans%MM+MM)%MM;
	}
	pr(ans);
	return 0;
} 

回复

11 条回复,欢迎继续交流。

正在加载回复...