UVa1635 - Irrelevant Elements(组合数)

来源:互联网 发布:java Renameto什么意思 编辑:程序博客网 时间:2024/05/02 03:09

题意:整个式子的和可以  化简为  sigma (C(n-1,i-1)*ai)

思路:只要判断C(n-1,i-1)能否被 m整除即可。

做法是先分解m的质因数,然后计算1!~(n-1)!  包含m的质因数的个数

C(n-1,i-1) = (n-1)!/((i-1)!*(n-i)!) 

只要判断 剩下的质因数的个数是否大于等于m的任一个质因数的个数即可

<pre name="code" class="cpp">#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<string>#include<algorithm>#include<queue>#include<cmath>using namespace std;typedef long long LL;const int maxp = 40000 + 10;const int maxn = 100000 + 10;int n,m;bool isPrime[maxp];vector<int> ret,prime,hp,cnt,tmp;vector<int> g[maxn];void getPrime(){    memset(isPrime,true,sizeof isPrime);    for(int i=2;i<maxp;i++){        if(isPrime[i]){            prime.push_back(i);            for(int j=i+i;j<maxp;j+=i){                isPrime[j]=false;            }        }    }}void getDigit(){    int tk=m;    for(int i=0;i<prime.size()&&prime[i]*prime[i]<=tk;i++){        if(tk%prime[i]==0){            int k=0;            hp.push_back(prime[i]);            while(tk%prime[i]==0){                tk/=prime[i];                k++;            }            cnt.push_back(k);        }    }    if(tk>1){        hp.push_back(tk);        cnt.push_back(1);    }}void init(){    cnt.clear();    hp.clear();    ret.clear();    getDigit();    for(int i=0;i<=n-1;i++) g[i].clear();    for(int i=0;i<=n-1;i++){        for(int j=0;j<hp.size();j++){            int d=0,t=i;            while(t){                d+=t/hp[j];                t/=hp[j];            }            g[i].push_back(d);        }    }}void solve(){    bool miden = false;    for(int i=2;i<=(n-1)/2+1;i++){        bool flag=true;        for(int j=0;j<hp.size();j++){            int d=g[n-1][j]-g[i-1][j]-g[n-i][j];            if(d<cnt[j]){                flag=false;                break;            }        }        if(flag){            ret.push_back(i);            if(i==(n-1)/2+1&&(n&1))miden=true;        }    }    tmp.clear();    tmp=ret;    if(n&1){        int i;        if(miden) i=tmp.size()-2;        else i=tmp.size()-1;        for(;i>=0;i--){            ret.push_back(n+1-tmp[i]);        }    }else{        for(int i=tmp.size()-1;i>=0;i--){            ret.push_back(n+1-tmp[i]);        }    }    printf("%d\n",ret.size());    if(ret.size()){        printf("%d",ret[0]);        for(int i=1;i<ret.size();i++)            printf(" %d",ret[i]);    }    puts("");}int main(){    getPrime();    while(~scanf("%d%d",&n,&m)){        init();        solve();    }    return 0;}


                                             
0 2
原创粉丝点击