codeforce 359D 二分+ 动态规划(sparse table)
原题链接:http://codeforces.com/problemset/problem/359/D
思路:首先对符合题目的长度(r-l)从0到n-1进行二分查找,对每一个长度进行check,看是否满足条件。
满足条件的话需要区间【l,r】内的最小值和最大公约数相等,如果暴力搜索,会超时,故采用st(sparse table)算法,建立table只需要O(nlgn)时间,查询是O(1),远远小于暴力搜索
st算法具体可参考http://baike.baidu.com/view/1536346.htm#2,只要适用于一段区间内的最大最小等值的计算。
AC代码如下:
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <string.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int MAXN = 300050;
int arr[MAXN];
int dp[MAXN][20];//gcd
int dq[MAXN][20];//min
int n;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
bool ok(int x)
{
int k = (int)(log((double)(x+1)) / log(2.0));
for(int i=0;i<n-x;i++)
{
int j = i+x; int Min = min(dq[i][k],dq[j - (1<<k) + 1][k]);
int g = gcd(dp[i][k],dp[j - (1<<k) + 1][k]);
if(g==Min)
return true;
}
return false;
}
void out(int x)
{
vector<int> v;
int k = (int)(log((double)(x+1)) / log(2.0));
if(x>0)
{
for(int i=0;i<n-x;i++)
{
int j = i+x;
int Min = min(dq[i][k],dq[j - (1<<k) + 1][k]);
int g = gcd(dp[i][k],dp[j - (1<<k) + 1][k]);
if(g==Min)
{
v.push_back(i);
}
}
}
else
{
for(int i=0;i<n;i++)
v.push_back(i);
}
cout<<v.size()<<" "<<( x>0?x:0)<<endl;
for(int i=0;i<v.size();i++)
cout<<v[i]+1<<" ";
cout<<endl;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
cin>>arr[i];
for(int i=0;i<n;i++)
{
dp[i][0] = arr[i];
dq[i][0] = arr[i];
}
for(int i=1;i<20;i++)
for(int j = 0;j<n;j++)
{
dp[j][i]=dp[j-1][i];
dq[j][i] = dq[j-1][i];
if(j+(1<<(i-1))<n)
{
dq[j][i] = min(dq[j][i-1],dq[j+(1<<(i-1))][i-1]);
dp[j][i] = gcd(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
} } int l = 0;int r = n-1;
while(l<r)
{
int mid = (l+r+1)/2;
if(ok(mid))
l = mid;
else
r = mid-1;
} out(l);
return 0;
}
codeforce 359D 二分+ 动态规划(sparse table)的更多相关文章
- RMQ ---- ST(Sparse Table)算法
[概述] RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返 ...
- 一维二维Sparse Table
写在前面: 记录了个人的学习过程,同时方便复习 Sparse Table 有些情况,需要反复读取某个指定范围内的值而不需要修改 逐个判断区间内的每个值显然太浪费时间 我们希望用空间换取时间 ST表就是 ...
- RMQ(ST(Sparse Table))(转载)
1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A ...
- 二分+动态规划 POJ 1973 Software Company
Software Company Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 1112 Accepted: 482 D ...
- codeforces 359D 二分答案+RMQ
上学期刷过裸的RMQ模板题,不过那时候一直不理解>_< 其实RMQ很简单: 设f[i][j]表示从i开始的,长度为2^j的一段元素中的最小值or最大值 那么f[i][j]=min/max{ ...
- codeforce 626E(二分)
E. Simple Skewness time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
- 【HDU 5808】 Price List Strike Back (整体二分+动态规划)
Price List Strike Back There are nn shops numbered with successive integers from 11 to nn in Bytelan ...
- BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...
- 【洛谷P1281 书的复制】二分+动态规划
分析 两个做法,一个DP,一个是二分. 二分:也就是二分枚举每个人分到的东西. DP:区间DP F[I][J]表示前i本书分给j个人用的最短时间 由于每一次j的状态由比j小的状态得出,所以要先枚举j, ...
随机推荐
- python之I/O多路复用
python IO多路复用 一.多路复用概念: 监听多个描述符(文件描述符(windows下暂不支持).网络描述符)的状态,如果描述符状态改变 则会被内核修改标志位,进而被进程获取进而进行 ...
- 交换两个数-c++实现
今天看了下交换数值的小程序,网上挺多的,整理了下,,因为参考较多,没一一给出链接,若原作者看到,可以留言,我会添加 // example_1_6_function_swap.cpp : 定义控制台应用 ...
- CentOS 6.5下搭建LAMP环境详细步骤
1.确认搭建LAMP所需的环境是否已经安装: [root@localhost ~]#rpm -q make gcc gcc-c++ zlib-devel libtool libtool-ltdl li ...
- 用tcc遇到的一个大坑
在centos6.5 x86_64服务器上编译安装完tcc, 版本0.9.25(在github上clone的),似乎一切正常 但当用tcc来编译"hello, world"程序时, ...
- 使用history.back()出现"警告: 网页已过期的解决办法"
原因: 表单提交页面中使用了 session_start 函数.由于我们后退浏览的是缓存页,而该函数会强制当前页面不被缓存. 解决: PHP: 此提示出现在一个POST提交的页面,点到其它页面后,通过 ...
- linux 驱动学习笔记01--Linux 内核的编译
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
- 《C++必知必会》学习笔记
转载:http://dsqiu.iteye.com/blog/1734640 条款一 数据抽象 抽象数据设计遵循步骤:(1)为类型取一个描述性的名字.(2)列出类型所能执行的操作,不要忘了初始化(构造 ...
- 如何异步创建文件夹(node)
模块fs作为node的核心模块之一,支持本地文件操作的接口,几乎对于所有的操作都提供同步和异步两种方案.例如,创建文件夹有mkdir和mkdirSync.不论对于mkdir还是mkdirSync,都需 ...
- kafka命令
./kafka-topics.sh --zookeeper ip:port --list ./kafka-topics.sh --create --topic test --zookeeper ip: ...
- Python-类的继承
类的继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制.继承完全可以理解成类之间的类型和子类型关系. 需要注意的地方:继承语法 class 派生类名(基类名):/ ...