UVA-1635 数学

UVA-1635

题意:

给定n个数a1,a2,a3.....an,依次求出相邻的两个数的和,最后成为一个数,问这个数模m的值与那些最初的数无关

例:a1,a2,a3, m=2 => a1+a2,a2+a3 => a1+2a2+a3 ,显然第二项无关。

代码:

//可以看出最后得到的式子符合杨辉三角,所以可以递推出所有的项的系数(c(i+1)=c(i)*(n-i)/(i+1)),
//但是数太大不能直接计算,可以将他们分解成 a1^p1*a2^p2*... 的形式,这样就只需要判断因子的指数的大小即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=100000;
int c[maxn+10];
int ans[maxn+10],prime[maxn+10],re[maxn+10],tot;
void init(int m,int p){
    tot=0;
    memset(re,0,sizeof(re));
    for(int i=2;i<=sqrt(m+0.5);i++){
        if(m%i==0){
            prime[++tot]=i;
            while(m%i==0){
                m/=i;
                re[tot]+=p;
            }
        }
    }
    if(m>1){
        prime[++tot]=m;
        re[tot]+=p;
    }
}
int solve(int m,int p){
    for(int i=2;i<=sqrt(m+0.5);i++){
        if(m%i==0){
            while(m%i==0){
                m/=i;
                c[i]+=p;
            }
        }
    }
    if(m>1) c[m]+=p;
    for(int i=1;i<=tot;i++){
        if(prime[i]>maxn) return 0;
        else if(c[prime[i]]<re[i])
            return 0;
    }
    return 1;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2){
        init(m,1);
        int cnt=0;
        memset(c,0,sizeof(c));
        n--;
        for(int i=0;i<n;i++){
            solve(n-i,1);
            int tmp=solve(i+1,-1);
            if(tmp) ans[++cnt]=i+2;
        }
        printf("%d\n",cnt);
        for(int i=1;i<=cnt;i++)
            printf("%d%c",ans[i],i==cnt?'\n':' ');
        if(cnt==0) printf("\n");//坑!!!
    }
    return 0;
}

 

posted @ 2017-08-14 09:16  luckilzy  阅读(326)  评论(0编辑  收藏  举报