口算训练

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 5642    Accepted Submission(s): 1234

Problem Description
小Q非常喜欢数学,但是他的口算能力非常弱。因此他找到了小T,给了小T一个长度为n的正整数序列a1,a2,...,an,要求小T抛出m个问题以训练他的口算能力。

每个问题给出三个正整数l,r,d,小Q需要通过口算快速判断al×al+1×...×ar−1×ar是不是d的倍数。

小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。

 
Input
第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。

每组数据第一行包含两个正整数n,m(1≤n,m≤100000),分别表示序列长度以及问题个数。

第二行包含n个正整数a1,a2,...,an(1≤ai≤100000),表示序列中的每个数。

接下来m行,每行三个正整数l,r,d(1≤l≤r≤n,1≤d≤100000),表示每个问题。

 
Output
对于每个问题输出一行,若是倍数,输出Yes,否则输出No。
 
Sample Input

1 5 4 6 4 7 2 5 1 2 24 1 3 18 2 5 17 3 5 35
 
Sample Output

Yes No No Yes
 
Source
"字节跳动杯"2018中国大学生程序设计竞赛-女生专场
 

Statistic | Submit | Discuss | Note

如果用传统的分解质因数方法,会超时
分解质因数的优化版,要结合素数筛法。

优化版也分为两种版本,首先是第一个版本。 打素数表法

(根据分解质因数的不一样,分为两个版本)

除了本题描述的以外,还有一种比较基础的优化,

就是先做出一个素数表

然后每次分解质因数的时候,直接取出所有素数

不需要枚举所有根号下的数了

所以一共三种优化

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> g[N]; //g[]的第一维[]下标是质因数,第二维存这个质数在序列里面哪个数的下标
/*
解释g[N] :
如果某个质因数  在序列里下标为1的数里面出现了多次
那就多次存储下标1 (重复存储)最终某个数的下标被g[p]存储了几次,就代表这个数有多少个p 质因数
*/ int primes[N],cnt;
bool st[N]; void init()
{for(int i=2;i<N;i++){if(!st[i]){primes[cnt++]=i;}for(int j=0;primes[j]*i<N;j++){st[primes[j]*i]=true;if(i%primes[j]==0){break;}}}
}void divide(int x,int idx) //对x分解质因数
{for(int i=0;st[x];i++)  //只要x是合数,就可以一直取筛选出来的素数 {int p=primes[i];if(x%p==0){while(x%p==0){x/=p;g[p].push_back(idx);  //存下标 }}} if(x>1) {int p=x;g[p].push_back(idx); }
}int main()
{init();int T;scanf("%d",&T);while(T--){for(int i=0;i<N;i++) g[i].clear(); int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int x;cin>>x;divide(x,i);}while(m--){int l,r,d;scanf("%d%d%d",&l,&r,&d);bool flag=true;//对d分解质因数 int x=d;for(int i=0;st[x];i++){int p=primes[i];int sum=0;if(x%p==0){while(x%p==0){x=x/p;sum++;} }int b=upper_bound(g[p].begin(),g[p].end(),r)-g[p].begin(); //比r大的下标int a=lower_bound(g[p].begin(),g[p].end(),l)-g[p].begin(); //大于等于l的下标 if(b-a<sum) //如果质因数数量不够{flag=false;break;} }if(x>1) {int p=x;int b=upper_bound(g[p].begin(),g[p].end(),r)-g[p].begin(); //比r大的下标int a=lower_bound(g[p].begin(),g[p].end(),l)-g[p].begin(); //大于等于l的下标 if(b-a<1){flag=false;}}if(flag) puts("Yes");else puts("No");}}return 0;
}

其次是第二个版本

/*
优化版本2:
(主要在分解质因数上和第一个版本不一样)
*/#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int primes[N],idx;
bool st[N];
int minp[N];//int a[N];
vector<int> g[N];void init()
{for(int i=2;i<N;i++){if(!st[i]){primes[idx++]=i;minp[i]=i;}for(int j=0;primes[j]*i<N;j++){st[primes[j]*i]=true;minp[primes[j]*i]=primes[j];if(i%primes[j]==0){break;}}}
}void divide(int x,int idx)
{while(x>1){int p=minp[x];while(x%p==0){x/=p;g[p].push_back(idx);}}
} int main()
{init();int T;scanf("%d",&T);while(T--){for(int i=0;i<N;i++) g[i].clear();int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int x;scanf("%d",&x);divide(x,i);}while(m--){int l,r,d;scanf("%d%d%d",&l,&r,&d);bool flag=true;int x=d;while(x>1){int p=minp[x];int sum=0;while(x%p==0){x/=p;sum++;}int b=upper_bound(g[p].begin(),g[p].end(),r)-g[p].begin();int a=lower_bound(g[p].begin(),g[p].end(),l)-g[p].begin();if(b-a<sum){//    cout<<" b is "<<b<<" a is "<<a<<endl;flag=false;break;}}if(flag) puts("Yes");else puts("No");}}return 0;
}

HDU6287 口算训练 【两种优化版分解质因数】【二分下标】相关推荐

  1. HDU6287 口算训练(唯一分解定理+二分)

    口算训练 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Sub ...

  2. 口算训练-(2018-女生赛)(二分+唯一分解定理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6287 题意:给你n个数,每个数都很大; 有q次询问,让你判断一下从下标为: [L,R]的范围内 能否通 ...

  3. 口算训练java_提高孩子口算能力的5大方法,超实用!(附练习,可打印)

    原标题:提高孩子口算能力的5大方法,超实用!(附练习,可打印) 来源: 网络 编辑:成长园(id:czy6688990) 小编提醒 关注成长园,后台回复"1201" 即可获取打印版 ...

  4. python口算训练出题

    python口算训练出题 为了给妹妹出算数题,编了一个乘除法的出题代码,省去了许多时间 图片 obj=open(r"C:\Users\12483\Desktop\math.txt" ...

  5. hdu 6287 口算训练(二分+质因数分解+思维)

    口算训练 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Sub ...

  6. 冒泡排序和其两种优化

    第一篇博客 会的算法的也不多 就用c++写个冒泡排序 #include <iostream> #include <iomanip> #include <cstring&g ...

  7. oracle 两种优化器,Oracle的优化器有两种优化方式(一)

    Oracle的优化器有两种优化方式(整理), 2010-04-13 RBO方式:基于规则的优化方式(Rule-Based Optimization,简称为RBO)  优化器在分析SQL语句时,所遵循的 ...

  8. MATLAB写的三维魔方解算GUI 两种算法(Thistlethwaite算法和Kociemba算法)

    大二的时候,没什么事情,打算用MATLAB做一个三阶魔方机器人,所以使用GUI做了个上位机,使用MATLAB编写的3阶魔方GUI,可以实现魔方状态设置(始末状态都可以设置),使用 patch 实现的魔 ...

  9. 试算平衡表两种方法比较

    试算平衡表的编制有两种方法,发生平衡法和余额平衡法,其中余额平衡法是发生余额法的再进一步. ORACLE 系统可以根据会计科目某一段或某一个分类账进行试算 这个小例子里面没有期初余额和期末余额 [@m ...

  10. pyhton的tkinter制作简易口算训练器

    前言 最近参加实习投递,发现好多家企业不管是什么岗位(研发or职能)都会考验到大家的数学能力 例如宝洁笔试直接就上了口算题,限时是真的紧张. 楼主不仅编程能力垃圾,数学能力也从小没有得到很好的锻炼(键 ...

最新文章

  1. 实现Java Socket 客户端服务端交互实例
  2. 500分求助,delphi里用standred来配置dbf文件
  3. boost::geometry::num_points用法的测试程序
  4. Wpf控件ListBox使用实例2
  5. oracle 中增加行,Oracle中实现FORM表单插入、锁定、更新行、删除行的包
  6. ICLR最高分论文揭秘模型泛化,GNN是潜力股
  7. 火热报名 |【 6月26日上海站】VCEC沙龙第5期:智能化技术在质量场景落地和实践...
  8. SAP链接外部数据库的实现方法
  9. pytorch GPU
  10. JAVA程序设计第十版第七章_java程序设计第七章答案
  11. IOS设计模式第二篇之单例设计模式
  12. RS232通讯数据解析C#
  13. 3.企业安全建设指南(金融行业安全架构与技术实践) --- 安全规划
  14. BZOJ4764弹飞大爷——LCT
  15. 微信小程序毕业设计 基于微信小程序外卖点餐系统开题报告
  16. 零基础学习 iOS 开发?如何系统学习 iOS ?
  17. 中国省,市,区 json数据
  18. Java基础 -> 线程池的底层⼯作原理
  19. “细雨湿衣看不见,闲花落地听无声”---超强作文
  20. 10 大话设计模式C++实现之模板方法模式

热门文章

  1. [ERR] 1273 - Unknown collation: ‘utf8mb4_0900_ai_ci‘
  2. 加载mysql的jdbc驱动_JDBC驱动加载
  3. 矩阵减法c语言程序,矩阵的加减法
  4. 打算做知识付费,所有了解一下视频加密
  5. Python——轮盘抽奖游戏
  6. Windows驱动开发(三)一个WDF入门实例
  7. 2-10配置Linux网络
  8. python爬取网易评论
  9. 手把手教你如何用VBA统计问卷调查表
  10. 通过mysql修改后台密码_怎么通过修改数据库修改网站后台的管理员密码?