洛谷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;
}

猜你喜欢

转载自www.cnblogs.com/suxxsfe/p/12431623.html