C++數論容斥原理—————無關的元素

題目描述;

對於給定的n個數a1,a2,...,an,依次求出相鄰兩數之和,將得到一個新數列。重複上述操作,最後結果將變成一個數。問這個數除以m的餘數與哪些數無關?

例如n=3,m=2時,第一次求和得到a1+a2,a2+a3,再次求和得到a1+2a2+a3,它除以2的餘數和a2無關。

輸入:

第1行:2個整數n和m(1<=n<=10^5, 2 <=m<=10^9)

輸出;

按升序列出與m無關的元素的序號,每行1個。

若與全部元素無關,輸出0

輸入樣例:

5 3

輸出樣例:

3

提示:

無。

思路分析:

此題的意思就是求楊輝三角上的第n行上的數,有哪些被m整除。

而想一想被m整除,那麼m所有的因子,這個數就一定有。

所以我們就可以用質因數的唯一分解求出因子。

然後再枚舉楊輝三角的數,當然在運用二項式定理與Legendre定理存儲m的因子相同的個數。

最後再比較它們的大小,一旦m的該因子個數比此數大,就可以判定他不是無關的元素。

代碼實現:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
ll n,m,w1[1000005],w2[1000005],p1[1000005],p2[1000005],tot1,num[1000005],tot2;
void sep(ll x)
{
    for(ll i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            tot1++;
            p1[tot1]=i;
            while(x%i==0)
            {
                x/=i;
                w1[tot1]++;
            }
        }
    }
    if(x>1)
    {
        tot1++;
        p1[tot1]=x;
        w1[tot1]=1;
    }
}
bool sep2(ll x,ll y)
{
    for(ll i=1;i<=tot1&&((p1[i]<=x)||(p1[i]<=y));i++)
    {
        int t=p1[i];
        while(x%t==0&&x)
        {
            x/=t;
            w2[i]++;
        }
        while(y%t==0&&y)
        {
            y/=t;
            w2[i]--;
        }
    }
    for(int i=1;i<=tot1;i++)
        if(w2[i]<w1[i])
            return 0;
    return 1;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    sep(m);
    for(int i=1;i<=n-2;i++)
    {
        if(sep2(n-i,i))
        {
            tot2++;
            p2[tot2]=i+1;
        }
    }
    if(tot2)
        for(int i=1;i<=tot2;i++)
            printf("%lld\n",p2[i]);
    else
        printf("0");
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章