codeforces 359D 二分答案+RMQ
上学期刷过裸的RMQ模板题,不过那时候一直不理解>_<
其实RMQ很简单:
设f[i][j]表示从i开始的,长度为2^j的一段元素中的最小值or最大值
那么f[i][j]=min/max{d[i][j-1], d[i+2^j-1][j-1]}
RMQ的ST算法:
void ST() //初始化
{
memset(RMQ,,sizeof(RMQ)); for(int i=;i<=n;i++)
RMQ[i][]=a[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
RMQ[i][j]=min(RMQ[i][j-],RMQ[i+(<<(j-))][j-]);
} int Query(int L,int R) //求a[L..R]区间的最值
{
int k=;
while((<<(k+))<=R-L+) k++;
int tb=gcd(GCD[L][k],GCD[R-(<<k)+][k]);
return tb;
}
-----------------------------------------------
再回到这道题。要求输出r-l的最大值
可以使用二分答案。
注意:r-l的值可以为0(即r==l),可以这样写:
l=; r=n;
while (r>=l)
{
int mid=(l+r)/; //mid: r-l
if (calc(mid)) //calc(mid): 判断mid答案是否符合要求
l=mid+;
else
r=mid-;
}
记得原来还刷过求最小值的二分答案(NOIP2010提高组 关押罪犯),是这样的:
//当年的代码略屎= = sol:=false;
l:=; r:=mx;
while l<r do
begin
mid:=(l+r) div ;
ok:=process(mid);
if ok then
begin
sol:=true;
r:=mid;
end
else
begin
l:=mid+;
sol:=true;
end;
end;
----------------------------------------
如何求区间所有元素的gcd?
不难想出,其实gcd和min(求区间最小值)有个一样的性质:
设在区间[l..r]中,[l..k]的gcd为m,[k+1..r]的gcd为n,
则整个区间[l..r]的gcd等于gcd(m,n)
有了这个性质,就可以用ST算法求gcd了。
-------------------------------------------
借用了neopenx大神的RMQ模板,Orz
#include <iostream>
#include <vector>
#include <cstring>
using namespace std; vector<int> ans;
int RMQ[][],GCD[][];
int T,n,l,r,mx,num;
int a[]; int gcd(int x,int y)
{
return (y==)?x:gcd(y,x%y);
} void ST()
{
memset(RMQ,,sizeof(RMQ));
memset(GCD,,sizeof(GCD)); for(int i=;i<=n;i++)
RMQ[i][]=GCD[i][]=a[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
{
RMQ[i][j]=min(RMQ[i][j-],RMQ[i+(<<(j-))][j-]);
GCD[i][j]=gcd(GCD[i][j-],GCD[i+(<<(j-))][j-]);
}
} bool Query(int L,int R)
{
if (L==R) return true;
int k=;
while((<<(k+))<=R-L+) k++;
int ta=min(RMQ[L][k],RMQ[R-(<<k)+][k]);
int tb=gcd(GCD[L][k],GCD[R-(<<k)+][k]);
if (ta==tb) return true;
else return false;
} bool calc(int x) //x: r-l
{
bool res=false;
for (int i=;i<=n-x;i++)
{
bool ok=Query(i,i+x);
if (ok)
{
res=true;
//cout<<"----"<<i<<" "<<i+x<<" "<<x<<endl; //record the answer,use vector
if (x==mx)
{
num++;
ans.push_back(i);
}
else if (x>mx)
{
num=;
mx=x;
ans.clear();
ans.push_back(i);
}
}
}
return res;
} int main()
{
mx=-;
num=;
ans.clear();
cin>>n;
for (int i=;i<=n;i++)
cin>>a[i]; ST(); l=; r=n;
while (r>=l)
{
int mid=(l+r)/; //mid: r-l
if (calc(mid))
l=mid+;
else
r=mid-;
}
cout<<num<<" "<<mx<<endl;
vector<int>::iterator ii;
for (ii=ans.begin();ii!=ans.end();ii++)
cout<<*ii<<" ";
cout<<endl; return ;
} /*
注意特殊情况:
5
2 3 5 7 11
计算时应把r-l=0也考虑进去
(r==l)
*/
codeforces 359D 二分答案+RMQ的更多相关文章
- Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论
n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...
- Electric Charges CodeForces - 623C (二分答案)
大意: 平面上n个点每个点坐标为(x,0)或(0,y), 求任意两点距离平方最大值的最小值. 二分答案, 转化为判定最大值是否<=e, 按$x$排序后, 因为固定左端点, $y$绝对值的最大值是 ...
- Codeforces 1132D(二分答案+堆)
题面 传送门 分析 二分答案,考虑如何判定 可以用贪心的方法,每次找最快没电的电脑,在没电前1单位时间给它充电 正确性显然 实现上可以维护一个堆,存储每个电脑电用完的时刻,每次从堆顶取出最小的一个给它 ...
- CodeForces 483B 二分答案
题目: B. Friends and Presents time limit per test 1 second memory limit per test 256 megabytes input s ...
- CodeForces 549H | 二分答案
参考了这个博客哇 #include<cstdio> #include<algorithm> #include<cstring> #define Max(a,b,c, ...
- CodeForces 359D (数论+二分+ST算法)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319 题目大意:给定一个序列,要求确定一个子序列,①使得该子序 ...
- Codeforces 700A As Fast As Possible(二分答案)
[题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)
链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划
There are n people and k keys on a straight line. Every person wants to get to the office which is l ...
随机推荐
- java7-4 继承的练习
1.Override和Overload的区别,Overload能改变返回值类型吗? 答: Override就是方法重写:在子类中,出现和父类中一模一样的方法声明的现象 Overload就是方法重载:在 ...
- java 15 - 6 List的方法
List集合的特有功能: A:添加功能 void add(int index,Object element):在指定索引处添加元素 B:获取功能 Object get(int index):获取指定索 ...
- 转: 使用virtualenv搭建独立的Python环境
转自: http://qicheng0211.blog.51cto.com/3958621/1561685 谢谢作者的辛苦付出 virtualenv可以搭建虚拟且独立的python环境,可以使每个项 ...
- 25个实用的jquery技巧
1. 去除页面的右键菜单 $(document).ready(function(){ $(document).bind(“contextmenu”,function(e){returnfalse; ...
- Android_firstClass
一个Project 创建后,大概的文件目录如下:在Android Studio每个Project,相当于Eclipse 的WorkSpace:每个Module(上图的app 目录)相当于Eclipse ...
- centos一键优化脚本
centos一键优化脚本:细节:http://oldboy.blog.51cto.com/2561410/1336488网络状态优化:http://oldboy.blog.51cto.com/2561 ...
- JS面向对象的几种写法
JS 中,面向对象有几种写法.归纳下,大概有下面这几种:工厂模式,构造函数模式,原型模式,构造函数与原型模式的混合使用,原型链继承,借用构造函数继承. 一.工厂模式 function person ( ...
- 设计模式——1.概述&UML类图和时序图
声明:本博客设计模式相关文章均整理和修改自网络,原文地址:图说设计模式 学习设计模式的3个层次—— 1.熟悉所有设计模式: 2.能够用代码实现: 3.运用到工作的项目中. 设计模式指导软件开发,学习设 ...
- Nutch搜索引擎(第3期)_ Nutch简单应用
1.Nutch命令详解 Nutch采用了一种命令的方式进行工作,其命令可以是对局域网方式的单一命令也可以是对整个Web进行爬取的分步命令. 要看Nutch的命令说明,可执行"Nutch&qu ...
- Android四大布局及其主要属性
布局: <LinearLayout></LinearLayout> <RelativeLayout></RelativeLayout> <Fram ...