[NOIP2009][vijos1814]细胞分裂(数学相关)
2016-11-11 23:37
302 查看
题目描述
传送门题解
题意实际上是要求最小的n,使sn≡0(modm1m2)呃,,其实没有这么麻烦。将s和m1质因数分解,假设
s=pa11pa22...pakk,m1=qb11qb22...qbkk,那么sn=s=pna11pna22...pnakk,m1m2=qm2b11qm2b22...qm2bkk
如果想要mm21|sn的话,必须满足q1,q2,...,qk这些质因子在p1,p2,...,pk中都出现过。并且对于相同的质因子,指数相除即为s的次数的最小值。那么n即为这些最小值里的最大值。
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 100005 int n,m1,m2,s,ans; int p ,q ,a ,b ; void calc(int x,int *p,int *a) { for (int i=2;i*i<=x;++i) if (x%i==0) { p[++p[0]]=i;a[p[0]]=0; while (x%i==0) x/=i,++a[p[0]]; } if (x>1) p[++p[0]]=x,a[p[0]]=1; } int gcd(int a,int b) { if (!b) return a; else return gcd(b,a%b); } void check() { int nowa=1;int Max=0; for (int i=1;i<=q[0];++i) { while (nowa<=p[0]&&p[nowa]!=q[i]) ++nowa; if (nowa>p[0]) return; Max=max(Max,(b[i]-1)/a[nowa]+1); } if (ans==-1) ans=Max; else ans=min(ans,Max); } int main() { scanf("%d",&n);scanf("%d%d",&m1,&m2); calc(m1,q,b);for (int i=1;i<=q[0];++i) b[i]*=m2; ans=-1; for (int i=1;i<=n;++i) { scanf("%d",&s); p[0]=0;calc(s,p,a); check(); } printf("%d\n",ans); }
总结
非常傻逼的一道题让我给搞残了。以后写代码要再细心一些,一旦不注意就会错误百出。相关文章推荐
- [NOIP2013][vijos1842]火柴排队(数学相关+离散化+bit)
- [NOIP2009普及] 细胞分裂
- noip2009 细胞分裂 (质因数分解,处理大数间能否整除)
- [BZOJ1025][SCOI2009]游戏(置换+背包dp+数学相关)
- [BZOJ1584][Usaco2009 Mar]Cleaning Up 打扫卫生(dp+数学相关优化)
- Vijos1775 CodeVS1174 NOIP2009 靶形数独
- [NOIP2015][CODEVS5131]求和(数学相关)
- 洛谷 P1070 Vijos 1815 [NOIP 2009]道路游戏
- 洛谷 P1069 [NOIP2009普及组 T3] 细胞分裂
- [BZOJbegin][NOIP十连测第五场]Walk(数学相关+树形dp)
- NOIP2009 细胞分裂
- [普及] NOIP 2009 细胞分裂
- NOIP 2011 提高组 选择客栈(vijos 1737)(方法:队列,数学)
- [NOIP2009][vijos1810]导弹拦截(枚举)
- NOIP2009普及组-细胞分裂
- [NOIP2009][vijos1809]三国游戏(贪心)
- 【NOIP】普及组2009 细胞分裂
- 小Y的数学作业(Hankson 的趣味题)[NOIP2009提高组][Codevs1172]
- NOIP2009普及组细胞分裂(数论)——yhx
- [BZOJbegin][NOIP十连测第五场]Travel(数学相关+乱搞)