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 ...
随机推荐
- java8-4 多态的练习以及题目
1./* 多态练习:猫狗案例*/ class Animal { public void eat(){ System.out.println("吃饭"); } } class Dog ...
- xshell5 启动显示 mfc110.dll msvcp110.dll 未找到问题 解决办法
1. 安装 Visual C++ Redistributable for Visual Studio 2012 x86版本 注意: 一定要安装x86版本.(xshell5是32位的程序) 微软的官方下 ...
- Android 屏幕适配(二)增强版百分比布局库(percent-support-lib)
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46767825: 本文出自:[张鸿洋的博客] 一 概述 上周一我们发布了Andr ...
- jQuery Ajax 操作函数及deferred对象
jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. 函数 描述 jQuery.ajax() 执行异步 H ...
- 在windows中,如何使用cmd命令行窗口正确显示编码为utf-8格式的文字
在windows中,如何使用cmd命令行窗口正确显示编码为utf-8格式的文字呢? 正确的步骤如下: 1, 打开cmd命令行窗口 2, 输入命令 >chcp 65001 数字65001代表的是c ...
- 阻塞与非阻塞IO step by step
谈到IO,阻塞.非阻塞,异步.同步是绕不开的话题.说实话,我也没搞清楚,网上查了许多资料,大家众说纷纭,一种比较靠谱的说法是:”在处理 IO 的时候,阻塞和非阻塞都是同步 IO,使用使用了特殊的API ...
- 014医疗项目-模块一:删除用户的功能l
删除用户的功能我们还是按照:Dao->Service->Action->页面调试这种顺序来写. Dao: 我们使用逆向工程生成的方法就好: SysuserMapper sysuser ...
- C语言错误: HEAP CORRUPTION DETECTED
程序源代码: //写文件两种方式(文本文件和二进制文件) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<std ...
- 敏捷软件开发 Agile software Development(转)
原文链接: http://www.cnblogs.com/kkun/archive/2011/07/06/2099253.html 敏捷软件开发 Agile software Development ...
- MVC出错案例之一:主外键映射失败
今天在编写DomainModel和DomainMapper,最后放到OnModelCreating中运行的时候,给我抛出了如下错误: One or more validation errors wer ...