luogu P4752
给定一个数字 A ,这个 A 由 a1,a2,...,aN 相乘得到。
给定一个数字 B ,这个 B 由 b1,b2,⋯,bM 相乘得到。
如果 A/B 是一个质数,请输出YES
,否则输出NO
。
输入输出格式
输入格式:
每个测试点包含多组数据,第一行读入一个整数 TT 表示数据组数,对于每组数据:
第一行输入两个整数 N,M ,分别表示 A 由 N 个数字相乘得到, B 由 M 个数字相乘得到。
第二行输入 N 个整数,分别表示组成 A 的 N 个数字。
第三行输入 M 个整数,分别表示组成 B 的 M 个数字。
保证对于一个数字,其在 {bi}中出现的次数不多于在 {ai} 中出现的次数。
输出格式:
对于每组数据:
如果 A/B 是一个质数,请输出
YES
,否则输出NO
。在输出
YES
或NO
后输出一个换行符。
输入输出样例
2
3 2
5 7 7
5 7
4 2
5 7 7 7
5 7
YES
NO
说明
1≤N≤100000
0≤M≤N
1≤ai,bi≤1012
1≤T≤10
∑N≤100000
吐槽两句:
说好的难度从普及-到省选呢?普及-难度呢?最低的只有 普及+提高-的吧,然而我看着都想省选题。
体面解读解题分析:
题面简洁易懂,只是根据数据范围,貌似如果相乘的话long long 恐怕都盛不开。
然而细细读题目你会发现,有句很重要的话(红色标注)
既然是A/B,那么 集合A 与 集合B中的元素可以先提前约分啊。
这句话说的数字在 B 中出现次数一定少于 A中的次数,那么这说明B中的数字可以在A中全部约去,那么B=1咯,所以A/B的值不就是A中所剩元素的乘积嘛。
少年,莫着急,等我把话说完。
A中元素的乘积难道就会小?绝对有数据会乘不开。
所以在约分完以后,需要一个比较有意思的判断。
你想A中元素的乘积,既然可以乘出来,那么一定就不是素数(prime).(emmm...说的在理)
还需要加一个判断,如果A中只剩下一个元素后,那么乘积就是这个数了,则需要判断一下这个数是否为素数。
1012大的数,用什么判断呢?
当然是 Miller_Rabin 算法判断了,下面给出了模板。
所以此题就解决完了。
Miller_Rabin模板
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std; ll add_mod(ll a,ll b,ll mod){ //快乘法 基于快速幂的二分思想
ll ans=; //由于考虑到取模数很大 快速幂会溢出
while(b){ //必须使用该方法
if(b&) //我这里写的是非递归版
ans=(ans+a)%mod;
a=a*%mod;
b>>=;
}
return ans;
} ll pow_mod(ll a,ll n,ll mod){ //快速幂 递归版
if(n>){
ll tmp=pow_mod(a,n>>,mod)%mod;
tmp=add_mod(tmp,tmp,mod);
if(n&) tmp=add_mod(tmp,a,mod);
return tmp;
}
return a;
} bool Miller_Rabbin(ll n,ll a){//米勒拉宾素数判断函数主体
ll d=n-,s=,i;
while(!(d&)){ // 先把(2^s)*d 算出来
d>>=;
s++;
}
ll t=pow_mod(a,d,n); //a^d取一次余判断
if(t== || t==-) //一或负一则可以声明这可能是质数
return ;
for(i=;i<s;i++){ //不是的话继续乘上s个2
if(t==n-) //(n-1)*(n-1)%n=1 这一步是优化
return ;
t=add_mod(t,t,n); // 快乘
}
return ;
} bool is_prime(ll n){
ll i,tab[]={,,,};//本来应该取[1,n]内任意整数
for(i=;i<;i++){ //但一般这几个数足以,不需要太多组测试
if(n==tab[i])
return ; //小判断小优化~
if(!n%tab[i])
return ;
if(n>tab[i] && !Miller_Rabbin(n,tab[i]))
return ;
}
return ;
} int main(){
ll n;
scanf("%lld",&n);
if(n<) printf("No");
else if(n==) printf("Yes");
else{
if(!n%) printf("No");
else if(is_prime(n))
printf("Yes");
else printf("No");
}
return ;
}
此题AC代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
#define N int(1e6+2)
#define M int(2e5+2)
#define ll long long
ll n,m,T;
ll a[N],b,c[N],tot;
map<ll,int> f;
bool vis[N];
ll sum;
ll add_mod(ll a,ll b,ll mod)
{
ll ans=;
while(b)
{
if(b&)
ans=(ans+a)%mod;
a=a*%mod;
b>>=;
}
return ans;
} ll pow_mod(ll a,ll n,ll mod)
{
if(n>)
{
ll tmp=pow_mod(a,n>>,mod)%mod;
tmp=add_mod(tmp,tmp,mod);
if(n&) tmp=add_mod(tmp,a,mod);
return tmp;
}
return a;
} bool Miller_Rabbin(ll n,ll a)
{
ll d=n-,s=,i;
while(!(d&))
{
d>>=;
s++;
}
ll t=pow_mod(a,d,n);
if(t== || t==-)
return ;
for(i=; i<s; i++)
{
if(t==n-)
return ;
t=add_mod(t,t,n);
}
return ;
}
bool is_prime(ll n)
{
ll i,tab[]= {,,,};
for(i=; i<; i++)
{
if(n==tab[i])
return ;
if(!n%tab[i])
return ;
if(n>tab[i] && !Miller_Rabbin(n,tab[i]))
return ;
}
return ;
}
int main()
{ scanf("%lld",&T);
while(T--)
{
sum=;
ll k=,p;
scanf("%lld%lld",&n,&m);
for(int i=; i<=n; i++)scanf("%lld",&a[i]),f[a[i]]++;;
for(int i=; i<=m; i++)scanf("%lld",&b),f[b]--;
for(int i=; i<=n; i++)
{
if(f[a[i]])k+=f[a[i]],f[a[i]]=,p=a[i];
}
f.clear();
if(k==)
{
n=p;
if(n<) printf("NO\n");
else if(n==) printf("YES\n");
else
{
if(!n%) printf("NO\n");
else if(is_prime(n))
printf("YES\n");
else printf("NO\n");
}
}
else printf("NO\n");
}
}
总的来说这题不是特别难,思想比较好。
luogu P4752的更多相关文章
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [luogu P2647] 最大收益(贪心+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...
- Luogu 考前模拟Round. 1
A.情书 题目:http://www.luogu.org/problem/show?pid=2264 赛中:sb题,直接暴力匹配就行了,注意一下读入和最后一句话的分句 赛后:卧槽 怎么只有40 B.小 ...
- luogu P2580 于是他错误的点名开始了
luogu P2580 于是他错误的点名开始了 https://www.luogu.org/problem/show?pid=2580 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边 ...
- CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)
CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...
- Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂)
Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂) Description 广义的斐波那契数列是指形如\[A_n=p*a_{n-1}+q*a_{n-2}\]的数列.今给定数列的两系数p和q, ...
- Luogu 1962 斐波那契数列(矩阵,递推)
Luogu 1962 斐波那契数列(矩阵,递推) Description 大家都知道,斐波那契数列是满足如下性质的一个数列: f(1) = 1 f(2) = 1 f(n) = f(n-1) + f(n ...
随机推荐
- E20180413-hm
skew adj. 斜的,歪的; [数学] 不对称的; [统计学] 歪斜,扭曲; vt. 歪曲; 曲解; 使歪斜; vi. 偏离,歪斜; 斜视; traversal n. 横越,横断物,(横 ...
- HDU 6092:Rikka with Subset(dp)
分析 很多个较小的数字可以随机组合成较大的数字,所以B数组从小到大开始遍历,除了空集,最小的那个存在的个数对应的数字必然是a数组中的数字. 每求出这一部分之后,更新后续的B序列. 分析完后,主要的难点 ...
- hdoj3790 【最短路】
这一题啊,其实还是很简单的~(A掉了就很简单啊~) 思路: 松弛,然后在里面维护一个小最短路~: A掉这一题,感觉松弛的理解又上了一个台阶,以及spfa的原理,最短路用到的原理就是松弛,先把图构造到最 ...
- c# 组件无法下断点
1. c#组件 2.断点能下,且运行中断点本身显示正常(正常实心红点,不是白底红圈) 3.运行中无法进入组件 4.主程序中,组件的实例无法被观测到,调试显示:无法计算得到这个对象 , 但是程序能运行 ...
- Codeforces732D Exams
显然要二分答案,然后对于一个天数,我们来判断是否可以通过所有考试,这里就贪心来安排就好了. 首先我们希望每门课的考试时间越晚越好,然后就是先复习最早开始的考试. #include <bits/s ...
- Selenium | 基础入门
在maven项目搭建环境: <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifact ...
- UltraEdit的免费激活方法
本来前段时间用UE编辑器用的好好的,然后今天突然提示我使用到期,需要购买激活.一脸懵逼中,只好再次激活,谁知道按照原来的方法激活的时候一直提示您输入的许可证id或密码错误 请您检查注册邮件并且重试. ...
- eclipse XML TAB键默认为四个空格
- C#程序A调用程序B的问题
C#程序A调用程序B,如果程序B中存在 string path1 = System.Environment.CurrentDirectory; 程序A中开启B进程的代码为: System.Diagno ...
- JAVA Map的使用
学JAVA那么多天了,所以就不写那啥了,哈哈 Map 是一个很实用的东西,它查询的速度也是飞快的.还有很多好的地方, 至于好在哪里,我也说不清. 还是用代码来说吧: import java.util. ...