[noip模拟]数字对<RMQ&二分>
数字对
【题目描述】
小H是个善于思考的学生,现在她又在思考一个有关序列的问题。
她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。
这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R - L。
小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。
【输入格式】
第一行,一个整数n.
第二行,n个整数,代表ai.
【输出格式】
第一行两个整数,num和val,表示价值最大的特殊区间的个数以及最大价值。
第二行num个整数,按升序输出每个价值最大的特殊区间的L.
【样例输入1】
5
4 6 9 3 6
【样例输出1】
1 3
2
【样例输入2】
5
2 3 5 7 11
【样例输出2】
5 0
1 2 3 4 5
【数据范围】
30%: 1 <= n <= 30 , 1 <= ai <= 32.
60%: 1 <= n <= 3000 , 1 <= ai <= 1024.
80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.
100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.
【思路】
题不是很难,就是可能一些细节注意不到或者优化想不到
我拿到题后的第一反应是一个数组f[i][j][k]表示从i开始的j位来记录这个区间的最小值和最大公约数
随便举一些例子就不难发现,其实要满足条件的区间,整除的那个数是这个区间最小而且是最大公约数
那么题就简单了,就是求最小值和最大公约数相同的区间,然后找到区间最大的并输出左端点
我们之前定义了一个f[i][j][k],然后结合一起的知识,我们不难有一个大胆的想法
就是用RMQ来处理这个小小细节,表示为gcdn[i][j]是从i位开始的2^j位这个区间的最大公约数
minn[i][j]是从i为开始的2^j位这个区间的最小值
这里一想出来,接下来就是区间的最大长度了。。。这个简单,枚举一下这个长度然后找gcd和min相同的区间
当然,枚举,不存在的,直接二分就行了。。。。另外一提,这题非常容易超时
所以我来提几个细节
1.在RMQ时的外循环,不能循环到int类型的边界,而是要根据n来定义,循环到log₂n次(注意不要搞成根号n了),j是代表2^j次方
2.在表示2^j次方不要直接用函数pow,要用位运算,位运算的时间消耗更小。。。
只有这样才不会超时
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#define maxn 500005
using namespace std;
int gcdn[maxn][],minn[maxn][],n,m,a[maxn];
int gcd(int a,int b){
if(b==)return a;
else return gcd(b,a%b);
}
void rmq(){
for(int j=;j<=(int)log2(n);j++){
for(int i=;i<=n;i++){
int new_=pow(2.0,j)+i-;
if(new_>n)continue;
minn[i][j]=min(minn[i][j-],minn[i+ (<<(j-))][j-]);
gcdn[i][j]=gcd(gcdn[i][j-],gcdn[i+ (<<(j-))][j-]);
}
}
}
int ans[maxn],num,val,len;
void change(int l,int r,int n){
if(l==r)return;
int mid=(l+r)>>;
int j=log2(mid+);
for(int i=;i<=n-mid;i++){
int a1,a2;
a1=min(minn[i][j],minn[i+mid- (<<j) + ][j]);
a2=gcd(gcdn[i][j],gcdn[i+mid- (<<j) + ][j]);
if(a1==a2){
num++;ans[num]=i;
}
}
if(num==)change(l,mid,n);
else{
val=mid;len=num;
num=;change(mid+,r,n);
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
gcdn[i][]=minn[i][]=a[i];
}
rmq();
change(,n-,n);
printf("%d %d\n",len,val);
for(int i=;i<=len;i++){
printf("%d ",ans[i]);
}
}
总结:
1.对于区间的最值一类问题,可以用RMQ解决
2.pow函数的使用要注意pow出来的值是浮点数,而且pow函数里的第一个数必须是浮点数,比如要求2^j,就是pow( 2.0, j ),当然这个细节是因为cena里会编译错误,自己是不会报错的
3.能用位运算就尽量用位运算,特别是循环中会多次执行一个语句,换成位运算后可以大大省下时间
4.注意区分一下log2和sqrt,两个出来的值不同,比如log2(64)=6,sqrt(64)=8,初中数学,相信就不用解释了
[noip模拟]数字对<RMQ&二分>的更多相关文章
- 数字对——RMQ+二分答案
题目描述 小H是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n). 这 ...
- 2019.01.20 NOIP模拟 迅雷(kruskal/二分+并查集)
传送门 题意简述:给一张带权无向图,有a,ba,ba,b两类特殊点和普通点,问使得至少有一个aaa和一个bbb连通所需要的所有边边权最小值的最大值是多少. 思路: 一眼发现可以二分,考虑怎么check ...
- 2018.10.02 NOIP模拟 矩阵分组(二分答案)
传送门 考场上并不会写二分的check函数,下来看了看题解发现真是妙极. 不难想到每次直接从四个角各按阶梯状拓展出合法区域A,再检验B是否合法就行了.(然而考场上写的弃疗了) 于是题解用了一些小技巧优 ...
- [NOIP模拟赛][并没有用二分][乱搞AC]
圆圈舞蹈 [问题描述] 熊大妈的奶牛在时针的带领下,围成了一个圆圈跳舞.由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时针走,到达 ...
- 【NOIP模拟题】【二分】【倍增】【链表】【树规】
3 计算几何3.1 题意描述花花对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目:首先,花花会在x 轴正半轴和y 轴正半轴分别挑选n 个点 ...
- hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 ...
- Nescafe #29 NOIP模拟赛
Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 【HHHOJ】NOIP模拟赛 捌 解题报告
点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...
随机推荐
- 简单说 用CSS做一个魔方旋转的效果
说明 魔方大家应该是不会陌生的,这次我们来一起用CSS实现一个魔方旋转的特效,先来看看效果图! 解释 我们要做这样的效果,重点在于怎么把6张图片,摆放成魔方的样子,而把它们摆放成魔方的样子,重点在于用 ...
- CSS+JS相应式导航菜单
响应式导航菜单 响应式导航菜单就是当网页在其他不同视口的样式,不同的设备需要不同的样式 需要掌握的知识 - 掌握媒体查询,如果你不是很懂那就看我写的CSS响应式布局 掌握CSS重的display:no ...
- OOM when allocating tensor of shape [] and type float [[node conv2d_224/kernel/Initializer/random_uniform/min (defined at ./intances/utils.py:19) ]]
当你们在用模型加载,tensorflow-gpu预测的时候,有没有出现这样的错误?? 经过网上的资料查阅,更多的解释是GPU的显存不足造成的,于是乎,我查看了一下GPU显存:nvidia-smi 不看 ...
- 微信小程序接入百度OCR(身份证识别)
微信小程序接入百度OCR(身份证识别) 1.接口描述 支持对二代居民身份证正反面所有8个字段进行结构化识别,包括姓名.性别.民族.出生日期.住址.身份证号.签发机关.有效期限,识别准确率超过99%:同 ...
- java套打快递单
package org.sq.common.utils; import org.apache.commons.codec.binary.Base64;import org.apache.http.en ...
- json中存整形数值,前端返回为空
实现目标: 在servlet中将整型数值转为json,然后在前端获取 问题描述: 前端获取为空,显示为:console.log打印为:{} 解决办法: 在servlet中将数值转为json格式再进行传 ...
- 如何为SpringBoot服务添加HTTPS证书
HTTPS是HTTP的安全版本,旨在提供数据传输层安全性(TLS).当你的应用不使用HTTP协议的时候,浏览器地址栏就会出现一个不安全的提示.HTTPS加密每个数据包以安全方式进行传输,并保护敏感数据 ...
- 使用selenium模拟登陆淘宝、新浪和知乎
如果直接使用selenium访问淘宝.新浪和知乎这些网址.一般会识别出这是自动化测试工具,会有反制措施.当开启开发者模式后,就可以绕过他们的检测啦.(不行的,哭笑) 如果网站只是对windows.na ...
- 用python实现LBP特征点计算
import cv2 import numpy as np def olbp(src): dst = np.zeros(src.shape,dtype=src.dtype) for i in rang ...
- JS循环嵌套的执行原理
[逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌 ...