zoukankan      html  css  js  c++  java
  • 唯一分解定理应用+组合数学

    题目:UVA 1635

    题目大意:

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

    分析:

    C(k,n)=(n-k+1)/k*C(k-1,n),如果直接去求C(i-1,n-1)会爆long long 。那么就用唯一分解定理先将m分解了,然后在对C(i-1,n-1)分解了,看他们的素因子的指数是否合理,如果合理就是倍数关系。所谓合理就是C(i-1,n-1)的每一个素因子指数都要大于等于m的素因子指数
    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    using namespace std;
    const int max_=1e5+5;
    int pow_prime[max_][2];
    int fen[max_];
    int num[max_];
    int tot;
    void putm(int n)
    {
        tot=0;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                int s=0;
                while(n%i==0)
                {
                    s++;
                    n/=i;
                }
                pow_prime[tot][0]=s;
                pow_prime[tot++][1]=i;
            }
        }
        if(n>1)
        {
            pow_prime[tot][0]=1;
            pow_prime[tot++][1]=n;
        }
    }
    bool check(int n,int k)
    {
        int x=n-k+1;
        int y=k;
        for(int i=0;i<tot;i++)
        {
            int p=pow_prime[i][1];
            int& q=fen[i];
            while(x%p==0)//fen数组会累加,相当于递推
            {
                q++;
                x/=p;
            }
            while(y%p==0)
            {
                q--;
                y/=p;
            }
        }
        for(int i=0;i<tot;i++)
        {
            if(fen[i]<pow_prime[i][0])
                return 0;
        }
        return 1;
    }
    int main()
    {
        int n, m;
        while(~scanf("%d %d",&n,&m))
        {
            putm(m);
            int sum=0;
            memset(fen,0,sizeof(fen));
            for(int i=1;i<n;i++)
            {
                if(check(n-1,i))
                {
                    num[sum++]=i+1;
                }
            }
            printf("%d
    ",sum);
            for(int i=0;i<sum;i++)
            {
                if(i==0)
                    printf("%d",num[i]);
                else
                    printf(" %d",num[i]);
            }
            printf("
    ");
        }
    }
    View Code
  • 相关阅读:
    leetCode 移动零 问题记录
    leetCode 加一 问题记录
    leetCode 两个数组的交集 II 问题记录
    leetCode 只出现一次的数字 问题记录
    leetCode 旋转数组 问题记录
    将本地项目上传到git
    RabbitMQ Linux 安装教程
    springboot RabbitMQ 配置
    linux——mysql5.5 安装遇到问题总结&解决方式
    Js预编译 GO和AO活动对象
  • 原文地址:https://www.cnblogs.com/linhaitai/p/10011772.html
Copyright © 2011-2022 走看看