CodeForces 359D (数论+二分+ST算法)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319
题目大意:给定一个序列,要求确定一个子序列,①使得该子序列中所有值都能被其中一个值整除,②且子序列范围尽可能大(r-l尽可能大)。
解题思路:
对于要求1,不难发现只有min(L,R)=gcd(L,R)时才行。其中gcd是L,R范围内的最大公约数,min是L,R范围内的最小值。
对于要求2,传统思路是r-l从大到小枚举,每次确定一个(L,R)范围,进行判断,直到可行。复杂度O(n^2)铁定TLE。
由于r-l的值是有序的,固采用二分。先枚举r-l的中间值,如果符合要求,则向右考虑,看看有没有更大的。否则向左。
当然这题的难度不止于此,尽管采用二分,但是光是枚举复杂度就有O(nlogn)了,再加上查询orz。
最初我使用的是线段树完成RMQ、以及GCD的Query , 复杂度O(n*logn*logn), CF跑到Test10就TLE了。
看了题解才发现要使用ST算法在O(1)的时间内完成RMQ和GCD。也是第一次碰到ST算法,看见刘汝佳的炒鸡简洁ST,给跪了。
#include "cstdio" #include "iostream" #include "vector" #include "algorithm" #include "math.h" #include "cstring" using namespace std; #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define maxn 3*100005 #define maxp 20 template <class T> inline bool read(T &ret) {char c;int sgn;if(c=getchar(),c==EOF) return 0; //EOFwhile(c!='-'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');ret*=sgn;return 1; } int gcd(int a,int b) {if(b!=0) return gcd(b,a%b);else return a;} int RMQ[maxn][maxp],GCD[maxn][maxp],val[maxn],n,cnt,range; vector<int> ans; void ST() {for(int i=1;i<=n;i++) RMQ[i][0]=GCD[i][0]=val[i];for(int j=1;(1<<j)<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++){RMQ[i][j]=min(RMQ[i][j-1],RMQ[i+(1<<(j-1))][j-1]);GCD[i][j]=gcd(GCD[i][j-1],GCD[i+(1<<(j-1))][j-1]);} } bool Query(int L,int R) {int k=0;while((1<<(k+1))<=R-L+1) k++;int a=min(RMQ[L][k],RMQ[R-(1<<k)+1][k]);int b=gcd(GCD[L][k],GCD[R-(1<<k)+1][k]);if(a==b) return true;else return false; } bool judge(int v) //枚举r-l {int cc=0;vector<int> tt;for(int i=1; v+i<=n; i++){if(Query(i,i+v)) //L=i,R=i+v; {cc++;tt.push_back(i);}}if(cc>0){ans=tt;cnt=cc;range=v;return true;}return false; } int main() {memset(RMQ,1,sizeof(RMQ));memset(GCD,1,sizeof(GCD));read(n);for(int i=1; i<=n; i++)read(val[i]);ST();int l=0,r=n-1,mid;while(l<=r) //二分 {mid=(l+r)>>1;if(judge(mid)) l=mid+1;else r=mid-1;}printf("%d %d\n",cnt,range);for(int i=0;i<ans.size();i++) {if(i>0) printf(" ");printf("%d",ans[i]);};printf("\n"); }
2808371 | neopenx | CodeForces 359D | Accepted | 51924 KB | 358 ms | GNU C++ 4.6 | 1981 B | 2014-10-03 15:00:32 |
CodeForces 359D (数论+二分+ST算法)相关推荐
- RMQ问题,加深对ST算法的理解(Sparse Table)
Sparse Table(稀疏表):简称ST 简介 ST 算法本质是动态规划. 时间复杂度为: 预处理:O(nlogn) 查询:O(1) 它 适宜用于 数据不再作出变化(也称离线) 的 区间最值 查询 ...
- 【原创】RMQ - ST算法详解
ST算法: ID数组下标: 1 2 3 4 5 6 7 8 9 ID数组元素: 5 7 3 1 4 8 2 9 8 1.ST算法 ...
- ST算法 - RMQ(区间最值问题)—— 倍增
文章目录 引入倍增: 例题1:区间和 例题2:Genius ACM 应用: ST算法 求解 RMQ(区间最值问题) 模板Code: 练习题: ST算法 维护区间最大公约数 例题:Pair of Num ...
- BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】
题目 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , 如名字所见,到处充满了数学的谜题. 现在你拥有n颗宝石,每颗宝石 ...
- 二分查找算法的一点改进
在计算机科学中,二分查找,是一种在有序数组中查找某一特定元素的搜索算法.这种搜索算法每一次比较都使搜索范围减半.第一篇二分查找的论文发表于1946年,然而第一个没有bug的二分查找算法却是在1962年 ...
- matlab 职坐标,机器学习入门之机器学习实战ByMatlab(四)二分K-means算法
本文主要向大家介绍了机器学习入门之机器学习实战ByMatlab(四)二分K-means算法,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助.前面我们在是实现K-means算法的时候,提到 ...
- RMQ问题(线段树算法,ST算法优化)
RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值 ...
- RMQ ST算法简介
RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...
- 二分查找算法的两种实现方式:非递归实现和递归实现
二分查找的条件是对一组有序数组的查找,这一点很容易忘记,在使用二分查找的时候先要对数组进行排序. 先说一下二分查找的思路:一个有序数组,想要查找一个数字key的下标,首先算出中间下标mid,利用mid ...
最新文章
- 【Netty】Netty 入门案例分析 ( Netty 模型解析 | Netty 服务器端代码 | Netty 客户端代码 )
- 79年后,中国人口将不到10亿,我国的生育率为何上不去了?
- Spring 基于注解(annotation)的配置之@Qualifier注解
- aodv协议C语言代码,AODV协议的运行方式
- php static 访问,使用PHP访问Static方法的最佳方法
- 容器编排技术 -- Kubernetes StatefulSet基本使用
- DEDE的简略标题标签的使用问题
- docker ubuntu16安装
- 地理住宅区的特点_高三地理复习专题讲解:民居特点与自然环境的关系
- C语言实现数字串转数字
- 怎么设置ppt页面的长度和宽度_FL Studio采样器该怎么设置? FL采样设置页面详解。...
- java将多张图片合成视频
- HTML5期末大作业:爱宠之家网站设计——蓝色版爱宠之家(5页) 致热爱动物网页设计作品 大学生爱宠专题网页设计作业模板 动物静态HTML网页模板下载
- PowerBI开发 第三篇:报表设计技巧
- 攻防世界---mfw
- 关于小米路由r3g,TTL刷openwrt救砖几个坑
- Jeaf Dean万字长文回顾2020谷歌技术发展(上)
- 实时显示当前时间(英文版)
- 化妆品企业迎来的机遇和挑战
- Channel L 自然拼读法 Teacher:Lamb
热门文章
- 如何在WPF中调用Winform控件
- 21/100. Two Sum
- 爬虫 - CNN Business
- HTML在手机上实现直接拨打电话以及发送短信
- ASP.NET 应用程序遭遇Server Application Unavailable问题的解决的方法
- android rild
- Deep learning:五(regularized线性回归练习)
- 操作html标签之找到标签(续)
- linux window命令大全,Windows 与 Linux->vim中常用命令大全
- java enumset_java.util.EnumSet.allOf()方法和实例的学习