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 ...
随机推荐
- python 字典 dict items values keys
dict.items() 1 >>> d = dict(one=1,two=2) 2 >>> it1 = d.items() 3 >>> it1 ...
- Unity插值函数Lerp()与增量时间Time.deltatime
一.Unity插值函数Lerp() 通过官方文档简单了解插值函数(https://docs.unity3d.com/ScriptReference/index.html),可以看到插值函数有很多 Ma ...
- USB转串口 FT232/PL2303芯片使用体会
现在笔记本上很少带有串口了,而串口又是做电子设计必备的通讯接口之一,好在USB转串口比较方便,市面上常用的USB转串口芯片有很多,最常见的有FT232.PL2303.CH340三种 原理:单片机的TX ...
- CSS常见的五大布局
本文概要 本文将介绍如下几种常见的布局: 一.单列布局 常见的单列布局有两种: header,content 和 footer 等宽的单列布局 header 与 footer 等宽,content 略 ...
- LightOj 1076 - Get the Containers (折半枚举好题)
题目链接: http://www.lightoj.com/volume_showproblem.php?problem=1076 题目描述: 给出n个数,要求分成m段,问这m段中最大的总和,最小是多少 ...
- JSP文件过大无法编译
JSP文件过大无法编译: The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding th ...
- printf格式化输出参数
1.类型 类型字符用以表示输出数据的类型,其格式符和意义如下表所示: 格式字符 意义 d 以十进制形式输出带符号整数(正数不输出符号) o 以八进制形式输出无符号整数(不输出前缀0) x,X 以十六进 ...
- XHTML 1.0 的三种 XML 文档类型 DOCTYPE
XHTML 1.0 的三种 XML 文档类型 XHTML 1.0 规定了三种 XML 文档类型 XHTML 1.0 Strict <!DOCTYPE html PUBLIC "-//W ...
- HDU 5808 Price List Strike Back bitset优化的背包。。水过去了
http://acm.hdu.edu.cn/showproblem.php?pid=5808 用bitset<120>dp,表示dp[0] = true,表示0出现过,dp[100] = ...
- hashTable 和 hashMap的区别
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,HashMap把Hashtable的contains方法去掉了,改成containsvalue和contai ...