uva1635 Irrelevant Elements(唯一分解定理)

题目链接:点击打开链接

题意:给定n个数a1,a2····an,依次求出相邻两个数值和,将得到一个新数列,重复上述操作,最后结果将变为一个数,问这个数除以m的余数与那些数无关?例如n=3,m=2时,第一次得到a1+a2,a2+a3,在求和得到a1+2*a2+a3,它除以2的余数和a2无关。1=<n<=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的一个素数,而且m> √(10^9),因此我们只需记录它即可

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

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn= 32000;
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 em[20];
int im;
void init()
{
    memset(pm,0,sizeof(pm));
    memset(em,0,sizeof(em));
    im=0;
    for(int i=0; i<nprime&&m>=prime[i]; i++)
    {
        if(m%prime[i]==0)
        {
            pm[im]=prime[i];
            while((m%prime[i]==0)&&(m/=prime[i]))
                em[im]++;
            im++;
        }
        if(n==0||n==1)
            break;
    }
    if(m>1)
    {
        pm[im]=m;
        em[im]=1;
        im++;
    }
}
bool getFactors(int x,int y)
{
    bool ff=true;
    for(int i=0; i<im; ++i)
    {
        while((x%pm[i]==0)&&(x/=pm[i]))
            em[i]--;
        while(y%pm[i]==0&&(y/=pm[i]))
            em[i]++;
        if(em[i]>0)
            ff=false;
    }
    return ff;
}
bool flag[100010];
int main()
{
    getPrime();
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        memset(flag,false,sizeof(flag));
        int ans=0;
        int 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;
}

收获:

每个整数的唯一分解式项数不多(long long 类型的数值最多20项,前21个素数相乘long long就溢出了)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 14:58:00

uva1635 Irrelevant Elements(唯一分解定理)的相关文章

UVa 1635 Irrelevant Elements (唯一分解定理 || 组合数学)

题目 题目大意 对于给定的\(n\)个数\(a_1\), \(a_2\), ···, \(a_n\), 依次求出相邻两数之和, 将得到一个新数列.重复上述操作, 最后结果将变成一个数.问这个数除以\(m\)的余数将与哪些数无关? 例如\(n = 3\), \(m = 2\)时, 第一次求和得到\(a_1 + a_2\), \(a_2 + a_3\), 再求和得到\(a_1 + 2a_2 + a_3\), 它除以\(2\)的余数和\(a_2\)无关.\(1 ≤ n ≤ 10^5\), \(2 ≤

【UVa1635】Irrelevant Elements - 唯一分解定理

题意 给你 \(n\) 个数,每次求出相邻两个数的和组成新数列.经过 \(n-1\) 次操作后,得到一个数.求这个数 \(mod \ m\) 与哪些项无关. 如:当 \(m=2 \ , \ n=2\) 时 \(a_1 \ , \ a_2 , a_3 \Rightarrow a_1+a_2 \ , \ a_2+a_3 \Rightarrow \ a_1+2a_2+a_3\) 则与 \(a_2\) 无关 思路 由二项式定理知道结果系数是杨辉三角的第 \(n-1\) 行,问题转换成判断有多少个 \(C

UVa1635 - Irrelevant Elements(质因数分解)

Young cryptoanalyst Georgie is investigating different schemes of generating random integer numbers ranging from 0 to m - 1. He thinks that standard random number generators are not good enough, so he has invented his own scheme that is intended to b

UVa1635 - Irrelevant Elements

通过观察发现其规律符合杨辉三角 需要注意的是最后ai的系数是C(i-1,n-1) 那么,问题就可以变成判断C(0,n-1),C(1,n-1)....C(n-1,n-1)哪些是m的倍数 只需要计算出m的唯一分解式中各个素因子在C(i-1,n-1)中的指数即可完成判断 然而为了节省时间,实际上我们只需算出m的每一个素因子在C(i-1,n-1)项中  含有几个即可 即我们将c(i-1,n-1)依次除以m的每一个素因子,直到无法整出,即可得出该项素因子的个数 紫薯上给出一个公式C(k,n)=(n-k+1

UVa1635 - Irrelevant Elements(组合数)

题意:整个式子的和可以  化简为  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>

组合数杨辉三角(Irrelevant Elements uva1635)

Young cryptoanalyst Georgie is investigating different schemes of generating random integer numbersranging from 0 to m - 1. He thinks that standard random number generators are not good enough, sohe has invented his own scheme that is intended to bri

【组合数的唯一分解定理】Uva1635

给出n.m,求得最终求和数列an=C(n-1,0)*x1 + C(n-1,1)*x2+...+C(n-1,n-1)*xn; 若xi与m无关,则an除以m的余数与xi无关,即余数不含xi的项: 输入:n,m 输出:ans  //无关项的总数: xi1 xi2 ...  //无关项,升序 Tips: 对于组合数的唯一分解定理 由于10^5级别的组合数必然会存在很大的项(long long甚至double都无法保存),要求得其唯一分解式只能采取按递推式分步分解,代码如下: bool check(int

Irrelevant Elements UVA-1635 (二项式定理)

vjudge链接 原题链接 乍一看似乎没什么思路,但是写几个简单的例子之后规律就变得很明显. 比如当 n=5 时,每一步计算后的结果如下: a1 a1+a2 a1+2a2+a3 a1+3a2+3a3+a4 a1+4a2+6a3+4a4+a5 显然系数"1, 4, 6, 4, 1"就是杨辉三角第五行. 故某一项的系数是否是题中 m 的倍数,就决定了最终得到的数除以 n 的余数和那一项是否有关. 二项式定理: 从中很容易得到前后两项的关系 C(n, k)=(n-k+1)/k*C(n, k-

HDU 1452 Happy 2004(唯一分解定理)

题目链接:传送门 题意: 求2004^x的所有约数的和. 分析: 由唯一分解定理可知 x=p1^a1*p2^a2*...*pn^an 那么其约数和 sum = (p1^0+p1^1^-+p1^a1)*-* (pn^0+pn^1^-+pn ) 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const