【Foreign】魔法 [组合数][质因数分解]

魔法

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  仅一行一个整数表示答案。

Sample Input

  4 10
  7 2 8 5

Sample Output

  2

HINT

  

Source

  我们找一下规律,显然发现是就是Σa[i]*C(n-1,i-1)。然后问题主要就转化为了怎么快速求组合数C(n,i)在模一个非质数情况下的值。

  首先我们先确定一个式子:

   然后我们立马想到了一个暴力分解质因数的方法。就是记录所有的(n-i+1)和(i)的质因数,然后用上面的质因数个数减去下面的质因数个数,剩下的乘起来,就不用求取模了。

  但是我们发现,这样显然会TLE,我们考虑如何优化。优化的话显然就是要找到一个办法不把多的质因数都彻底分解出来。我们来继续思考:

  我们可以先求出模数的质因数,再对于(n-i+1)和(i)分解质因数。这时候如果质因数和模数的质因数一样,由于不互质没有逆元,就把它记录下来,等下用快速幂乘起来就行了。那么这时候其余的质因数就可以直接求逆元了,由于模数不是质数,我们运用这个公式:(phi暴力求即可)

  这样做的话,由于模数的质因数是个数有限的,拆解其余数可以减少很多部分,那么效率就可以得到保证啦。

Code

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 using namespace std;
 8 typedef long long s64;
 9
10 const int Max = 1000005;
11 const int ONE = 1000005;
12
13 int n,x,MOD;
14 int a[ONE];
15 int f[Max],p[Max],p_num;
16 int Num[Max];
17 int Ans;
18
19 int get()
20 {
21         int res=1,Q=1;    char c;
22         while( (c=getchar())<48 || c>57)
23         if(c==‘-‘)Q=-1;
24         if(Q) res=c-48;
25         while((c=getchar())>=48 && c<=57)
26         res=res*10+c-48;
27         return res*Q;
28 }
29
30 int Quickpow(int a,int b)
31 {
32         int res=1;
33         while(b)
34         {
35             if(b&1) res=(s64)res*a%MOD;
36             a=(s64)a*a%MOD;
37             b>>=1;
38         }
39         return res;
40 }
41
42 void Deal_prime(int x)
43 {
44         for(int i=2;i*i<=x;i++)
45         if(!(x%i))
46         {
47             p[++p_num]=i;
48             while(!(x%i)) x/=i;
49         }
50         if(x>1) p[++p_num]=x;
51 }
52
53 int gcd(int a,int b) {int r=a%b; while(r) {a=b;b=r;r=a%b;} return b;}
54 int phi(int x) {int res=0; for(int i=1;i<x;i++)if(gcd(i,x)==1) res++;return res;}
55
56 int Add(int x,int P)
57 {
58         if(!x || x==1) return x;
59         for(int i=1;i<=p_num;i++)
60         {
61             while(!(x%p[i]))
62             {
63                 x/=p[i];
64                 Num[p[i]]+=P;
65             }
66             if(x==1) break;
67         }
68         return x;
69 }
70
71 int main()
72 {
73         n=get();    MOD=get();
74         Deal_prime(MOD);
75         int Phi = phi(MOD);
76
77         int C=1;
78         int record=1;
79         for(int i=1;i<=n;i++)
80         {
81             x=get();
82             Ans = (Ans+ (s64)record * x % MOD) % MOD;
83             if(i==n) break;
84             C = (s64)C * Add(n-i,1) % MOD * Quickpow(Add(i,-1),Phi-1) % MOD;
85             record=C;
86             for(int j=1;j<=p_num;j++)
87                 record= (s64)record * Quickpow(p[j],Num[p[j]]) % MOD;
88         }
89
90         printf("%d",Ans);
91 }

时间: 2024-10-08 23:49:31

【Foreign】魔法 [组合数][质因数分解]的相关文章

【BZOJ2227】【ZJOI2011】看电影 [组合数学][质因数分解]

看电影 Time Limit: 10 Sec  Memory Limit: 259 MB[Submit][Status][Discuss] Description 到了难得的假期,小白班上组织大家去看电影.但由于假期里看电影的人太多,很难做到让全班看上同一场电影,最后大家在一个偏僻的小胡同里找到了一家电影院.但这家电影院分配座位的方式很特殊,具体方式如下: 1. 电影院的座位共有K个,并被标号为1…K,每个人买完票后会被随机指定一个座位,具体来说是从1…K中等可能的随机选取一个正整数,设其为L.

Codevs 1313 质因数分解

1313 质因数分解 题目描述 Description 已知正整数 n是两个不同的质数的乘积,试求出较大的那个质数 . 输入描述 Input Description 输入只有一行,包含一个正整数 n. 输出描述 Output Description 输出只有一行,包含一个正整数p,即较大的那个质数. 样例输入 Sample Input 21 样例输出 Sample Output 7 #include<iostream> #include<cstdio> #include<cm

HDU 3988 n!质因数分解

Harry Potter and the Hide Story Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2324    Accepted Submission(s): 569 Problem Description iSea is tired of writing the story of Harry Potter, so, l

HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少.(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000) 思路:因为x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质.要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,可以

求n!质因数分解之后素数a的个数

n!质因数分解后P的个数=n/p+n/(p*p)+n/(p*p*p)+......直到n<p*p*p*...*p //主要代码,就这么点东西,数学真是厉害啊!幸亏我早早的就退了数学2333 do { n/=m; w+=n; }while(n);

3164 质因数分解

3164 质因数分解 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description (多数据)给出t个数,求出它的质因子个数. 数据没坑,难度降低. 输入描述 Input Description 第一行 t 之后t行 数据 输出描述 Output Description t行 分解后结果(质因子个数) 样例输入 Sample Input 2 11 6 样例输出 Sample Output 1 2 数据范围及提示 Data

莫比乌斯函数-质因数分解

1240 莫比乌斯函数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出.梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号.(据说,高斯(Gauss)比莫比乌斯早三十年就曾考虑过这个函数). 具体定义如下: 如果一个数包含平方因子,那么miu(n) = 0.例如:miu(4), miu(12), miu(18) = 0. 如果一个数不包含平方因子,并且有k个不同的质因子,那么miu(n)

质因数分解(0)&lt;P2012_1&gt;

质因数分解 (prime.cpp/c/pas) [问题描述] 已知正整数n是两个不同的质数的乘积,试求出较大的那个质数. [输入] 输入文件名为prime.in. 输入只有一行,包含一个正整数n. [输出] 输出文件名为prime.out. 输出只有一行,包含一个正整数p,即较大的那个质数. [数据范围] 对于60%的数据,6 ≤ n ≤ 1000. 对于100%的数据,6 ≤ n ≤ 2*109.

51nod 1240 莫比乌斯函数 (质因数分解)

1240 莫比乌斯函数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 取消关注 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出.梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号.(据说,高斯(Gauss)比莫比乌斯早三十年就曾考虑过这个函数). 具体定义如下: 如果一个数包含平方因子,那么miu(n) = 0.例如:miu(4), miu(12), miu(18) = 0. 如果一个数不包含平方因子,并且有k个不同的质因