UVA 1635-Irrelevant Elements(唯一分解定理)

来源:互联网 发布:电磁场与无线技术 知乎 编辑:程序博客网 时间:2024/04/29 10:11

原题链接:点击打开链接

题意:给定n个数a1,a2····an,依次求出相邻两个数值和,将得到一个新数列,重复上述操作,最后结果将变为一个数,问这个数除以m的余数与那些数无关?例如n=3,m=2时,第一次得到a1+a2,a2+a3,在求和得到a1+2*a2+a3,它除以2的余数和a2无关。1=<n&lt;=10^5, 2=<m<=10^9

思路:

1、首先我们可以发现对于给定的n其实每项的系数就是C(n-1,i-1),所以我们只需要找到每项的系数对m取余是否为0即可

2、由于m的取值范围为10^9,所以我们只需要筛选 √(10^9)的素数,然后对m进行分解;如果分解后m>1,说明当前m的是一个素数,而且m> √(10^9),因此我们只需记录它即可

3、根据C(n,k)=C(n,k)*(n-i+1)/i;(根据这个公式我们可以发现C(n,k)*(n-i+1)一定能整除i),对m分解式中的素数进行操作即可,具体见代码

这题虽然不难,但我WA了好几次,花了好久才发现是取消同步的问题,这是个坑,看来不能随便用取消同步o(╯□╰)o

/*************************************************************************    > File Name: 1635.cpp    > Author: Clannad    > Mail: 821199012@qq.com    > Created Time: Mon 11 July 2016 09:03:28 PM************************************************************************/#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <algorithm>#include <sstream>#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include<string>#include <ctime>using  namespace std;typedef  long  long  ll;const int inf=0x3f3f3f3f;const int maxn=32000;//32000*32000=1024e6;int prime[maxn+1];int nprime;void  getprime(){    int m=sqrt(maxn+0.5);    for(int i=2 ; i<m ; i++)if(!prime[i])        for(int j=i*i ; j<=maxn ; j+=i)prime[j]=1;    nprime=0;    for(int i=2 ; i<=maxn ; i++){        if(!prime[i])            prime[nprime++]=i;    }}int n,m;int pm[20];int km[20];int cnt;void init(){    memset(pm,0,sizeof(pm));    memset(km,0,sizeof(km));    cnt=0;    for(int i=0 ; i<nprime&&m>=prime[i] ; i++){        if(m%prime[i]==0) {            pm[cnt]=prime[i];            while((m%prime[i]==0)&&(m/=prime[i]))                km[cnt]++;            cnt++;        }        if(n==0||n==1)break;    }     if(m>1){            pm[cnt]=m;            km[cnt]=1;            cnt++;    }}bool  getfactors(int x,int y){    bool f=true;    for(int i=0 ; i<cnt ; i++){        while((x%pm[i]==0)&&(x/=pm[i]))            km[i]--;        while(y%pm[i]==0&&(y/=pm[i]))            km[i]++;        if(km[i]>0)f=false;    }    return f;}bool flag[100010];int main(){//    std::ios::sync_with_stdio(false);//    #ifndef ONLINE_JUDGE//        freopen("inF.txt", "r", stdin);//    #endif    getprime();    while(cin>>n>>m){        init();        memset(flag,false,sizeof(flag));        int  ans=0,ends=0;        for(int i=1 ; i<=n ; i++){            if(getfactors(n-i,i)){                flag[i+1]=true;                ans++;                ends=i+1;            }        }         printf("%d\n",ans);         if(ans!=0){            for(int i=1; i<ends; i++)                if(flag[i])                    printf("%d ",i);            printf("%d",ends);        }        printf("\n");    }    return 0;}


0 0
原创粉丝点击