fzu 1753 Another Easy Problem(n!的素因子分解)

来源:互联网 发布:c socket 端口复用 编辑:程序博客网 时间:2024/05/17 00:52
Problem 1753 Another Easy Problem

Accept: 382    Submit: 1731
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 

 Problem Description

小TT最近学习了高斯消元法解方程组,现在他的问题来了,如果是以下的方程,那么应该如何解呢?

C(n1,m1)==0 (mod M)

C(n2,m2)==0 (mod M)

C(n3,m3)==0 (mod M)

................

C(nk,mk)==0 (mod M)

小TT希望你告诉他满足条件的最大的M

其中C(i,j)表示组合数,例如C(5,2)=10,C(4,2)=6...

 Input

输入数据包括多组,每组数据的第一行是一个正整数T(1<=T<=150)表示接下来描述的T个方程

接下来T行,每行包括2个正整数ni,mi (1<=mi<=ni<=100000)

 Output

输出一行答案,表示满足方程组的最大M。

 Sample Input

3100 150 160 1

 Sample Output

10
 
题意:求t个组合数c(n,m)的最大公约数。
思路:c(n,m)=n!/((n-m)!*m!),将每个组合数分解素因子,写成唯一分解式,那么取每个组合数共同的素因子的最小数量值
作为该素因子的幂,然后所有素因子相乘即可。

 
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <map>#include <cmath>#include <cstdlib>#define L(rt) (rt<<1)#define R(rt) (rt<<1|1)#define ll __int64#define eps 1e-6using namespace std;const int maxn = 100005;const int INF = 1000000000;int prime[maxn];bool vis[maxn];int num[maxn], n[155], m[155];int cnt, minnum;void select_prime(){    memset(vis, false, sizeof(vis));    cnt = 0;    vis[0] = vis[1] = true;    for(ll i = 2; i < maxn; i++)        if(!vis[i])        {            prime[cnt++] = i;            for(ll j = i * i; j < maxn; j += i)                vis[j] = true;        }}void cal(int n1, int n2, int n3, int d){    for(int i = 0; i < cnt && prime[i] <= minnum; i++) //素因子分解    {        int c = 0, temp;        if(prime[i] <= n1)                  {            temp = n1;            while(temp)            {                c += temp / prime[i];                temp /= prime[i];            }        }        if(prime[i] <= n2)        {            temp = n2;            while(temp)            {                c -= temp/ prime[i];                temp /= prime[i];            }        }        if(prime[i] <= n3)        {            temp = n3;            while(temp)            {                c -= temp/ prime[i];                temp /= prime[i];            }        }        if(!d) num[i] = c;        else num[i] = min(num[i], c);    }}int main(){    select_prime();    int t;    while(~scanf("%d", &t))    {        minnum = INF;        memset(num, 0, sizeof(num));        for(int i = 0; i < t; i++)        {            scanf("%d%d", &n[i], &m[i]);            if(n[i] < minnum) minnum = n[i];        }        for(int i = 0; i < t; i++)        cal(n[i], m[i], n[i] - m[i], i);        ll ans = 1;        for(int i = 0; i < cnt; i++)        if(num[i])        {            for(int j = 0; j < num[i]; j++)            ans *= prime[i];        }        printf("%I64d\n", ans);    }    return 0;}


原创粉丝点击