上学期刷过裸的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的更多相关文章

  1. 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 ...

  2. Electric Charges CodeForces - 623C (二分答案)

    大意: 平面上n个点每个点坐标为(x,0)或(0,y), 求任意两点距离平方最大值的最小值. 二分答案, 转化为判定最大值是否<=e, 按$x$排序后, 因为固定左端点, $y$绝对值的最大值是 ...

  3. Codeforces 1132D(二分答案+堆)

    题面 传送门 分析 二分答案,考虑如何判定 可以用贪心的方法,每次找最快没电的电脑,在没电前1单位时间给它充电 正确性显然 实现上可以维护一个堆,存储每个电脑电用完的时刻,每次从堆顶取出最小的一个给它 ...

  4. CodeForces 483B 二分答案

    题目: B. Friends and Presents time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. CodeForces 549H | 二分答案

    参考了这个博客哇 #include<cstdio> #include<algorithm> #include<cstring> #define Max(a,b,c, ...

  6. CodeForces 359D (数论+二分+ST算法)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319 题目大意:给定一个序列,要求确定一个子序列,①使得该子序 ...

  7. Codeforces 700A As Fast As Possible(二分答案)

    [题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...

  8. Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)

    链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...

  9. 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 ...

随机推荐

  1. Android Studio系列教程一--下载和安装

    原文链接:http://stormzhang.com/devtools/2014/11/25/android-studio-tutorial1/ 背景 相信大家对Android Studio已经不陌生 ...

  2. smarty缓存控制

    第一步初始化配置文件中设置 如果当前访问的模板有缓存就不需要连接数据库那些代码了,如果要模板局部不缓存,要写在iscache外,模板中用{nocache}

  3. 纯CSS3制作九款可爱复古相机

    前言 掐指一算,快两个月没写博客分享了.好吧,我就只是在准备校招而已.现在已经有满意的offer了,所以我就回来啦!这两个月过得挺煎熬也挺充实的.具体细说估计得长篇大论,我就不闲扯了.总之呢,越努力, ...

  4. 关于js中onclick字符串传参问题

    规则: 外变是“”,里面就是‘’外边是‘’,里边就是“”   示例: var a="111"; var html="<a onclick='selecthoods( ...

  5. linux添加时间提示符

    给PS1添加\t [root@lanny ~]# echo $PS1 [\u@\h \W]\$ [root@lanny ~]# export PS1="[\u@\h \W\t]\$" ...

  6. linux下的zip命令

    1.把/home目录下面的mydata目录压缩为mydata.zipzip -r mydata.zip mydata #压缩mydata目录2.把/home目录下面的mydata.zip解压到myda ...

  7. 在PLSQL中编译复杂的java(转)

    原文地址:在PLSQL中编译复杂的java PLSQL中可以编译运行JAVA程序. 一个简单的例子: create or replace and compile java source named x ...

  8. ScrollView 简单出错

    ScrollView can host only one direct child 主要是ScrollView内部只能有一个子元素,即不能并列两个子元素,所以需要把所有的子元素放到一个LinearLa ...

  9. [VIM] 格式化代码

    快速使用vim格式化代码 在vim的编辑模式i下直接ESC退出道命令模式之后直接敲入如下命令: gg=G        将全部代码格式化 nG=mG    将第n行到第m行的代码格式化 注:如果ESC ...

  10. Spring MVC实现文件下载

     下载文件① 下载文件需要将byte数组还原成文件. 首先使用mybatis将数据库中的byte数组查出来,指定文件名(包括格式).然后使用OutputStream将文件输入 @RequestMapp ...