suxxsfe

一言(ヒトコト)

洛谷P1771 方程的解

P1771 方程的解
都知道这个题可以用隔板法做
把这个\(g(x)\)想象为.....\(g(x)\)个苹果?
因为解是正整数,所以给这些“苹果”分组的时候每组最少有一个
然后我们在这\(g(x)\)个苹果形成的\(g(x)-1\)个空隙中插入\(k-1\)个板就把它分成了\(k\)
所以答案是\(\binom{g(x)-1}{k-1}\)
然而组合数要用到除法,这题又要高精
不过高精除低精好像也没有很难,莫名恐惧
我们可以给每个数质因数分解,记录每个质因数出现次数,乘法时加一,除法时减一就行了然而这样并没有啥用
不过这种方法可以运用在答案要模一个数,但模数不是质数不能求逆元的情况下
要提前筛质数,一开始我居然认为\(n\)的质因数最大不超过\(\sqrt{n}\),直接手打质数表,结果一直WA

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	int x=0,y=1;
	char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int p[1006],notp[1006];
int num[1006],a[10005];
inline void getprime(int n){
	for(reg int i=2;i<=n;i++){
		if(notp[i]) continue;
		p[++p[0]]=i;
		for(reg int j=i+i;j<=n;j+=i) notp[j]=1;
	}
}
inline int power(int a,int b){
	reg int ret=1;
	while(b){
		if(b&1) ret=(ret*a)%1000;
		a=(a*a)%1000;b>>=1;
	}
	return ret;
}
inline void fen(int x,int k){
	for(reg int i=1;i<=p[0]&&x>1;i++){
		for(;!(x%p[i]);x/=p[i])
			num[i]+=k;
	}
}
inline void mul(int x){
	for(reg int i=1;i<=a[0];i++) a[i]*=x;
	for(reg int i=1;i<a[0];i++) a[i+1]+=a[i]/10,a[i]%=10;
	for(;a[a[0]]>9;a[0]++) a[a[0]+1]+=a[a[0]]/10,a[a[0]]%=10;
}
int main(){
	int k=read()-1,x=read()%1000;
	x=power(x,x)-1;
//		std::printf("%d %d\n",k,x);
	getprime(std::max(k,x));
	a[0]=a[1]=1;
	for(reg int i=k+1;i<=x;i++) fen(i,1);
	for(reg int i=2;i<=x-k;i++) fen(i,-1);
	for(reg int i=1;i<=p[0];i++){
		for(reg int j=1;j<=num[i];j++) mul(p[i]);
	}
	for(reg int i=a[0];i;i--) std::printf("%d",a[i]);
	return 0;
}
posted @ 2020-03-06 23:17  suxxsfe  阅读(180)  评论(0编辑  收藏  举报