P1771 方程的解_NOI导刊2010提高(01)

P1771 方程的解_NOI导刊2010提高(01)

按题意用快速幂把$g(x)$求出来

发现这不就是个组合数入门题吗!

$k$个人分$g(x)$个苹果,每人最少分$1$个,有几种方法?

根据插板法,显然答案为$C(g(x)-1,k-1)$

蓝后写个高精度。(我曾经十分天真地认为$ans<=10^{50}$)

这里用压位+结构体重载高精。可以应对$ans<=10^{24*7}$的数据。

注意:存在x,P,$(x^x) \% P!=(x\% P)^{(x\% P)} \% P$

#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
using namespace std;
int max(int a,int b){return a>b?a:b;}
const int W=10000000;//压7位
int x,k;
struct bigsum{
    int a[25],len;
    bigsum(){memset(a,0,sizeof(a));len=0;}
    bigsum operator + (const bigsum &tmp) const{
        bigsum c; int x=0;
        c.len=max(len,tmp.len);
        for(int i=1;i<=c.len;++i){
            c.a[i]=a[i]+tmp.a[i]+x;
            x=c.a[i]/W;c.a[i]%=W;
        }
        for(;x;x/=W) c.a[++c.len]=x%W;
        return c;
    }
    void print(){//注意压位高精输出时每一位的前导0
        printf("%d",a[len]);
        for(int i=len-1;i>=1;--i){
            for(int j=10;a[i]*j<W;j*=10) putchar(48);
            printf("%d",a[i]);
        }
    }
}C[1001][1001];
int Pow(int x,int y){
    int res=1;
    for(;y;y>>=1,x=1ll*x*x%1000)
        if(y&1) res=1ll*res*x%1000;
    return res;
}
int main(){
    scanf("%d%d",&k,&x); x=Pow(x%1000,x);
    if(!x){puts("0");return 0;} 
    for(int i=0;i<x;++i)
        for(int j=0;j<=i;++j){
            if(!j||j==i) C[i][j].a[C[i][j].len=1]=1;
            else C[i][j]=C[i-1][j]+C[i-1][j-1];
        }//杨辉三角递推
    C[x-1][k-1].print();
    return 0;
}

 

posted @ 2018-11-04 11:50  kafuuchino  阅读(268)  评论(0编辑  收藏  举报