CodeForces - 222C Reducing Fractions(唯一分解定理)
题目链接:点击查看
题目大意:给出两个数组,数组a表示的是分子的因数,数组b表示的是分母的因数,求约分后的答案
题目分析:一看题目挺简单的,但是在输出的那里这个题目做了特定的要求,题目首先给出的是1e5个数,每个数最大到1e7,然后输出的时候最多只能输出1e5个数,每个数最大也只能到1e7,这就导致了我们无法构造答案,本来我想的是用两个1e7的sum数组分别记录分子和分母的所有素因子,最后一起输出即可,因为2是最小的素数,所以一个不超过1e7的数,最多只能拆成20个素数,而1e5个数最多只能拆成2e6个数,并不是很大,一开始这样写了一发,交上去WA掉了,原因就是输出超过限制长度了,所以这个题需要换一种思考方式,因为输入和输出的数量还有大小关系都非常相似,那么我们能不能直接在原数组上进行约分呢?多余的都视作1就行了,经过zx学长的提醒后,我尝试性的写了一发,没想到还真的给过了。。
大概就是运用两次唯一分解定理吧,第一次用到的时候是中规中矩的分解素因子,这里我一开始打了一个1e5的素数表用来加速分解的整个过程,第二次用到的时候就是约分了,对于其中的一些细节进行了改动,具体的看代码吧,这个题目也可以算做一个小模拟,所以看代码比看文字说明要清晰多了
代码:
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef unsigned long long ull;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int pri[N];int cnt=0;bool vis[N];int a[N],b[N];int sum1[10000000],sum2[10000000];//储存素因子void P()//欧拉线性筛
{for(int i=2;i<N;i++){if(!vis[i])pri[cnt++]=i;for(int j=0;j<cnt&&pri[j]*i<N;j++){vis[pri[j]*i]=true;if(i%pri[j]==0)break;}}
}void only(int sum[],int x)//中规中矩的唯一分解定理
{for(int i=0;i<cnt&&pri[i]*pri[i]<=x;i++){if(x%pri[i]==0){while(x%pri[i]==0){x/=pri[i];sum[pri[i]]++;//在数组中出现的次数加一}}if(x==1)break;}if(x>1)sum[x]++;
}void del(int sum[],int& x)
{int temp=1;//记录当前的值,最后会还给xfor(int i=0;i<cnt&&pri[i]*pri[i]<=x;i++){if(x%pri[i]==0){while(x%pri[i]==0){x/=pri[i];if(sum[pri[i]])//若该因子在分子或分母中出现了,即可以约分sum[pri[i]]--;else//若没出现,或者已经被约没了,就要在原来的地方保留,即乘上就行temp*=pri[i];}}if(x==1)break;}if(x>1){if(sum[x])sum[x]--;elsetemp*=x;}x=temp;//将储存的值还给x
}int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);P();//打个素数表int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)//读入分子,将其唯一分解到sum1中{scanf("%d",a+i);only(sum1,a[i]);}for(int i=1;i<=m;i++)//读入分母,将其唯一分解到sum2中{scanf("%d",b+i);only(sum2,b[i]);}for(int i=1;i<=n;i++)//用分母对sum1约分del(sum2,a[i]);for(int i=1;i<=m;i++)//用分子对sum2约分del(sum1,b[i]);printf("%d %d\n",n,m);//最后原样输出for(int i=1;i<=n;i++)printf("%d ",a[i]);printf("\n");for(int i=1;i<=m;i++)printf("%d ",b[i]);return 0;
}
CodeForces - 222C Reducing Fractions(唯一分解定理)相关推荐
- Tennis Game CodeForces - 496D(唯一分解定理,费马大定理)
Tennis Game CodeForces - 496D 通过排列组合解决问题. 首先两组不同素数的乘积,是互不相同的.这应该算是唯一分解定理的逆运用了. 然后是,输入中的素数,任意组合,就是n的因 ...
- CF思维联系–CodeForces - 222 C Reducing Fractions(数学+有技巧的枚举)
ACM思维题训练集合 To confuse the opponents, the Galactic Empire represents fractions in an unusual format. ...
- 唯一分解定理一篇就够了
如果与唯一定理一起应用需要用到素数筛,可以看这篇文章: 线性筛判断素数 唯一分解定理: 任何一个大于1的自然数 N,如果N不为质数,**那么N可以唯一分解成有限个质数的乘积: 这里P1<P2&l ...
- 欧几里得算法与唯一分解定理
整理的算法模板合集: ACM模板 目录 最大公约数与最大公倍数 唯一分解定理 快速分解质因子 最大公约数与最大公倍数 最多O(logn)O(logn)O(logn) int gcd(int a, in ...
- FZU 1075 分解素因子【数论/唯一分解定理/分解素因子裸模板】
[唯一分解定理]:https://www.cnblogs.com/mjtcn/p/6743624.html 假设x是一个正整数,它的值不超过65535(即1<x<=65535),请编写一个 ...
- 唯一分解定理(算术基本定理)详解——hdu5248和lightoj1341
算数分解定理(唯一分解定理): 定义: 任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 N=P1a1 P2a2P3a3-Pnan,这里P1<P2<P3-& ...
- Gym-101466K Random Numbers(线段树,数学,唯一分解定理)
给一棵树,树上每个节点有一个权值,有两个操作,RAND操作查询u的子树乘积是多少以及有多少因数,SEED操作把节点u乘上v n,q <= 1e5.数值小于等于1e9,最大的质因数不超过13 组队 ...
- LightOJ - 1236 (唯一分解定理)
题意:求有多少对数对(i,j)满足lcm(i,j) = n,1<=i<=j, 1<=n<=1e14. 分析:根据整数的唯一分解定理,n可以分解为(p1^e1)*(p2^e2)* ...
- 牛客 - 阶乘(唯一分解定理)
题目链接:点击查看 题目大意:给出一个 p ,求出最小的 n! 使得 p 可以整除 n! 题目分析:因为 p 高达 1e9 ,可以考虑sqrt(n)的算法,也就是唯一分解定理了,分解之后对于每个质因子 ...
最新文章
- GIT常用基础命令总结
- 重定向程序无法决定链接类型 解决方案
- java字符串操作_Java的字符串操作
- java小程序扑克牌_用Java来写一个模拟斗地主发牌的小程序
- Android学习之网上商城(上)
- OpenShift / RHEL / DevSecOps 汇总目录
- vue和react的区别是什么?
- MacOS之Chrome弹框:代理要求提供用户名和密码(已解决)
- steam安裝位置linux,steam盒子
- 谷歌浏览器设置信任_Win10系统下谷歌浏览器怎么添加信任网址/站点
- jass Timer详解
- Thread线程中的stop方法过时问题
- H3C S3600 交换机NTP对等体模式的配置
- 没有美术基础如何学好平面设计?
- 《Kali Linux渗透测试的艺术》—第2章2.3节安全测试方法论
- Chrome插件 Redux DevTools
- c语言程序实践感受心得,C语言实践心得体会
- 深入理解git内部原理
- Outlook2016隐藏收藏夹
- python模拟微信登陆抢券