Number Sequence(hdu4390)

Number Sequence

Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 895 Accepted Submission(s):
374

Problem Description

Given a number sequence
b1,b2…bn.
Please count how many number
sequences a1,a2,...,an satisfy the condition
that
a1*a2*...*an=b1*b2*…*bn
(ai>1).

Input

The input consists of multiple test cases.
For each
test case, the first line contains an integer n(1<=n<=20). The second line
contains n integers which indicate b1,
b2,...,bn(1<bi<=1000000,
b1*b2*…*bn<=1025).

Output

For each test case, please print the answer module 1e9
+ 7.

Sample Input

2

3 4

Sample Output

4

Hint

For the sample input, P=3*4=12.

Here are the number sequences

that satisfy the condition: 2 6 3 4 4 3 6 2

题意:
给定b1---bn n个数,让你求出满足a1*a2*....*an-1*an(ai>1)=b1*b2*...*bn的种数。

思路:
先对每一个b分解质因数,统计每个质因子的个数,每个质因数不相互影响,可以单独考虑。首先考虑一种质因数放的总数,应明白 m个相同的数放进n个不同的盒子中(盒子可以为空)的总的种数为C(n-1,n+m-1).运用隔板法:实际上就是把m个数分成n组,每组可以为空,我们加上n-1个隔板,选出隔板所在的位置,相邻隔板之间的位置都放数,就有C(n-1,n+m-1)种了。
对每一质因数,运用上面的公式分别放进n个不同的盒子中,然后根据乘法原理,就能计算出答案了。

但是此时计算的答案并不是我们想要的,因为ai不能为1,故盒子不能为空,所以要用到容斥原理了。
运用容斥原理加上0盒子个为空的情况,减去k1*1个盒子为空的情况加上k2*2个盒子为空的情况...

k1、k2、ki怎样得到呢?
设 f[i]-放入i个数能够为空的种数,g[i]-放入i个数不能为空的种数,求g[n]。

考虑n=3时,
f[3]=g[3]+C(3,1)*g[2]+C(3,2)*g[1],
f[2]=g[2]+C(2,1)*g[1],
f[1]=g[1].
化简能得到g[3]=f[3]-C(3,1)*f[2]+C(3,2)*f[1].
根据数学归纳法能得到g[n]=f[n]-C(n,1)*f[n-1]+C(n,2)*f[n-2]-...

ps:http://acm.hdu.edu.cn/showproblem.php?pid=4390

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define LL __int64

const int N=1010;
const int M=1000010;
const LL MOD=1000000007;
const int INF=0x7fffffff;
const double eps=1e-7;
const double PI=acos(-1.0);

LL n,k,f[N],p[N],c[505][505];
//c记录组合数,f记录因子,p记录对应因子数

void init()//组合数[下a C b上]  C(a,b)=C(a-1,b)+C(a-1,b-1);公式递归;
{
    for(LL i=0;i<=500;i++)
    {
        c[i][0]=c[i][i]=1;
        for(LL j=1;j<i;j++)
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
    }
}

LL work()
{//容斥原理
    LL temp,ans;
    ans=0;
    for(LL i=0;i<n;i++)
    {
        temp=c[n][i];
        for(LL j=0;j<k;j++)
            temp=(temp*c[n-i+p[j]-1][n-i-1])%MOD;//c(n+m-1,n-1)
        if(i%2 == 0)
            ans=(ans+temp)%MOD;
        else
            ans=((ans-temp)%MOD+MOD)%MOD;;
    }
    return ans;
}

void Join(LL i,LL t)
{
    LL j;
    for(j=0;j<k;j++)
        if(f[j] == i)
        {
            p[j]+=t;
            break;
        }
    if(j == k)
    {
        f[k]=i;
        p[k++]=t;
    }
}
int main()
{
    init();
    LL a,i,j,t;
    while(scanf("%I64d",&n)!=EOF)
    {
        k=0;
                for(i=0;i<n;i++)
        {
            scanf("%I64d",&a);

            //求质因数及个数

            t=0;
            for(j=2;j*j<=a;j++)
            {
                while(a%j==0)
                {
                    a/=j;
                    t++;
                }
                if(t>0)
                   Join(j,t);
            }
            if(a>1)
                Join(a,1);
        }

        printf("%I64d\n",work());
    }
    return 0;
}

思路篇,需要好好体会。。。

Number Sequence(hdu4390)

时间: 2024-07-30 22:51:19

Number Sequence(hdu4390)的相关文章

HDU 5014 Number Sequence ( 构造 )

HDU 5014 Number Sequence ( 构造 ) 题目意思: 给出一个数列 由0 - n 组成 然后需要构造一个数列 (也是由0-n组成),使得 sum(A[i] ^ B[i])的值最大. 分析: 异或不能出现比这个数大的情况,,所以要从大的数往前找. 现计算出当前判断数的二进制位的位数m,然后再与2^m - 1进行异或,这样会保证最大,具体为什么,自己可以想一想 比如: 5 - 101 -- 3位 - 对应 111 101 ^ 111 = 010 代码: #include <cs

ACM—Number Sequence(HDOJ1005)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 主要内容: A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the value of f(n). 看到这样的公式很容易想到递归调用求解,但是在本题中n的取

hdu 5014 Number Sequence (贪心)

Number Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 697    Accepted Submission(s): 332 Special Judge Problem Description There is a special number sequence which has n+1 integers. F

Number Sequence(kmp)

欢迎参加——每周六晚的BestCoder(有米!) Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15007    Accepted Submission(s): 6582 Problem Description Given two sequences of numbers : a[1], a[2],

(HDU)1005 -- Number Sequence(数列)

问题描述 数列定义如下: f(1)= 1,f(2)= 1,f(n)=(A * f(n-1)+ B * f(n-2))mod 7. 给定A,B和n,你要计算f(n)的值. 输入 输入由多个测试用例组成. 每个测试用例在一行(1 <= A,B <= 1000,1 <= n <= 100,000,000)中包含3个整数A,B和n.三个零表示输入结束,此测试用例不进行处理. 输出 对于每个测试用例,在一行上输出f(n)的值. 样例输入 1 1 3 1 2 10 0 0 0 样例输出 2 5

SDUT 2044 Number Sequence(循环)

Number Sequence Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the value of f(n). 输入 The inpu

ACM学习历程——HDU 5014 Number Sequence (贪心)(2014西安网赛)

Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● a i ∈ [0,n] ● a i ≠ a j( i ≠ j ) For sequence a and sequence b, the integrating degree t is defined as follows(“?” denotes exclus

HDU 1005 Number Sequence(数列)

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) [Description] [题目描述] A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the

Number Sequence (HDoj1005)

Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Given A, B, and n, you are to calculate the value of f(n). Input The input consists of multiple test cases. Each test case co