hdu 5407 CRB and Candies(组合数+最小公倍数+素数表+逆元)2015 Multi-University Training Contest 10
2015-08-21 17:00
267 查看
题意:
输入n,求c(n,0)到c(n,n)的所有组合数的最小公倍数。
输入:
首行输入整数t,表示共有t组测试样例。
每组测试样例包含一个正整数n(1<=n<=1e6)。
输出:
输出结果(mod 1e9+7)。
感觉蛮变态的,从比赛开始我就是写的这道题,比赛结束还是没写出来……
期间找到了逆元,最小公倍数,组合数的各种公式,但是爆了一下午tle。
比赛结束,题解告诉我,公式秒杀法……
但是公式看不懂,幸好有群巨解说,所以有些听懂了,但还是需要继续思考才能弄懂。
题解:
设ans[i]表示i的所有组合数的最小公倍数。
设f[i]表示从1到i的正整数的最小公倍数。
然后获得从f[i]到ans[i]的公式——ans[i] = f[i+1]/i。 anss[i-1] = (f[i]*inv[i])%Mod;
然后获得求f[i]的公式——
if(i == p^k) f[i] = f[i-1]*p;
else f[i] = f[i-1];
接下来需要做的就是找到那些i == p^k了。
解题步骤:
1. 打素数表;
2. 由素数表寻找i == p^k;
3. f[1] = 1,打f[]数组表和ans[]数组表;
4. 输入数据;
5. 根据输入数据和ans[]表输出答案。
我认为还有其他方法,因为ac的程序的运行时间从15ms到900+ms都有。更多方法持续寻找中。
我的(根据题解的)代码——
View Code
输入n,求c(n,0)到c(n,n)的所有组合数的最小公倍数。
输入:
首行输入整数t,表示共有t组测试样例。
每组测试样例包含一个正整数n(1<=n<=1e6)。
输出:
输出结果(mod 1e9+7)。
感觉蛮变态的,从比赛开始我就是写的这道题,比赛结束还是没写出来……
期间找到了逆元,最小公倍数,组合数的各种公式,但是爆了一下午tle。
比赛结束,题解告诉我,公式秒杀法……
但是公式看不懂,幸好有群巨解说,所以有些听懂了,但还是需要继续思考才能弄懂。
题解:
设ans[i]表示i的所有组合数的最小公倍数。
设f[i]表示从1到i的正整数的最小公倍数。
然后获得从f[i]到ans[i]的公式——ans[i] = f[i+1]/i。 anss[i-1] = (f[i]*inv[i])%Mod;
然后获得求f[i]的公式——
if(i == p^k) f[i] = f[i-1]*p;
else f[i] = f[i-1];
接下来需要做的就是找到那些i == p^k了。
解题步骤:
1. 打素数表;
2. 由素数表寻找i == p^k;
3. f[1] = 1,打f[]数组表和ans[]数组表;
4. 输入数据;
5. 根据输入数据和ans[]表输出答案。
我认为还有其他方法,因为ac的程序的运行时间从15ms到900+ms都有。更多方法持续寻找中。
我的(根据题解的)代码——
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define LL long long const int N = 1000010; const int Mod = 1000000007; int n, t; LL ans, mid; LL inv ; LL anss ; bool su2 ; int su , su1 ; LL f ; //f[i]表示1~i的最小公倍数 void table() { inv[1] = 1; for(int i = 2; i < N; i++) //求i的逆元 { inv[i] = inv[Mod%i]*(Mod-Mod/i) % Mod; } memset(su2, 1, sizeof(su2)); memset(su1, 0, sizeof(su1)); su2[0] = su2[1] = 0; //求N以内的素数 su2[2] = 1; for(int i = 3; i < N; i++) su2[i] = i%2 == 0 ? 0 : 1; for(int i = 3; i <= sqrt(N*1.0); i++) { if(su2[i]) { for(int j = i*i; j <= N; j += 2*i) { su2[j] = 0; } } } int k = 0; for(int i = 0; i < N; i++) //打N以内的素数表 { if(su2[i] == 1) su[k++] = i; } for(int i = 0; i < k; i++) //寻找满足p^k的数,其中p为素数,k为正整数 { LL mid = su[i]; while(mid < N) { su1[mid] = su[i]; mid *= su[i]; } } f[1] = 1; //打N以内的1~i的最小公倍数表 for(int i = 2; i < N; i++) { if(su1[i]) f[i] = f[i-1]*su1[i]; else f[i] = f[i-1]; f[i] %= Mod; anss[i-1] = (f[i]*inv[i])%Mod; //答案表 } } int main() { //freopen("test.in", "r", stdin); //freopen("test.out", "r", stdout); table(); scanf("%d", &t); while(t--) { scanf("%d", &n); printf("%I64d\n", anss ); } return 0; }
View Code
相关文章推荐
- vs2010下配置CUDA出现kernel launch failed问题,内核无效
- Windows Server 2012如何部署Domain Controller
- WinMain与wWinMain,win32的字符集问题
- RAID
- hdu 3635 Dragon Balls(加权并查集)2010 ACM-ICPC Multi-University Training Contest(19)
- INSTALL_FAILED_OLDER_SDK
- INSTALL_FAILED_INSUFFICIENT_STORAGE
- 画布Canvas与画笔Paint
- retain,copy,assign,strong,weak,autorelease,nonatomic,atomic等得使用及区别
- POJ - 3846 Mountain Road 动归
- cassandra中对节点失败与否的探测方法, the Phi accrual Failure Dector,附论文
- 血族 第一季 The Strain Season 1 (2014)
- 模仿Airbnb的悬浮搜索框动画
- pygal and matplotlib(again)
- org.hibernate.LazyInitializationException: failed to lazily initialize a collection..的解决方案
- Rails - 将日期格式字符串转换为秒整数
- 什么是领域驱动设计(Domain Driven Design)?
- raid
- TIME_WAIT 太多的解决办法
- GrailsDispatcherServlet中的doDispatch方法