UVA1635 Irrelevant Elements

题意:给定一个序列,依次求出相邻两个数字的和,将得到一个新序列,重复上述过程直到最后的结果是是一个数。求最后的数除m的余数和原序列中的那些数无关。

题解:模拟可以得出最后一个数是原序列的线性和。没一项的系数恰好满足杨辉三角的规律。C(k,n)=(n-k+1)/k*C(k-1,m)。用这个可以0(n)的复杂度推出系数。但是由于数据很大,如果直接推的话,要用大数处理,过于麻烦。考虑到这里只关心那些系数是m的倍数,对于很大的数我们可以用唯一分解定理,把他以素数因子指数的形式处理,而且指数的关系是可以通过C(k,n)=(n-k+1)/k*C(k-1,m)这个关系式递推的。

ac代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int n,m;
int prime[10001];
int e[10001];
int c[100001];
int init()// 唯一分解定理 
{
    int ret=0;
    for(int i=2;i*i<=m;i++)
    {
        if(m%i==0)
        {
            prime[ret]=i;
            while(m%i==0)
            {
                e[ret]++;
                m/=i;
            }
            ret++;
        }
    }
    if(m>1)
    {
        prime[ret]=m;
        e[ret++]++;
    }
    return ret;
}
int e2[100001];
int check(int len)
{
    for(int i=0;i<len;i++)
    {
        if(e2[i]<e[i]) return 0;
    }
    return 1;
}
int main()
{
    while(cin>>n>>m)
    {
       // cout<<sum<<endl;
        memset(e,0,sizeof(e));
        int ret=0;
        queue<int> out;
        memset(c,0,sizeof(c));
        memset(e2,0,sizeof(e2));
        int sum=init();//
        c[0]=1;
        for(int i=1;i<n;i++)
        {
            int temp=n-1-i+1;// 对应n为多少要理清楚
            int zz=i;
           // cout<<temp<<' '<<zz<<endl;
            for(int j=0;j<sum;j++)// 递推指数关系的时候,由于有除法,可能出限小数,所以我们分子,分母分开处理
            {
                if(temp%prime[j]==0)
                {
                    while(temp%prime[j]==0)
                    {
                        e2[j]++;
                        temp=temp/prime[j];
                   //     cout<<1<<endl;
                    }
                }
                if(zz%prime[j]==0)
                {
                    while(zz%prime[j]==0)
                    {
                        e2[j]--;
                        zz=zz/prime[j];
                  //      cout<<2<<endl;
                    }
                }
            }

            if(check(sum))
            {
                ret++;
                out.push(i+1);
            }
        }

        cout<<ret<<endl;
        if(ret!=0)
        {
            cout<<out.front();
            out.pop();
        }
        while(!out.empty())
        {
             cout<<' '<<out.front();
             out.pop();
        }
        cout<<endl;
    }
    return 0;
}

 

posted @ 2017-07-17 16:05  猪突猛进!!!  阅读(230)  评论(0编辑  收藏  举报