倍增算法总结 ( 含RMQ模板)
部分题目来自《算法竞赛设计进阶》
问题
给定一个长度为n的数列A,有m个询问,每次给定一个整数T,求出最大的k,满足a[1],a[2]……a[k]的和小于等于T(不会打sigma)
第一反应是二分,这个时候的复杂度是logn
还有第二种解法,用倍增的思想,复杂度为logk(所求答案)。显然倍增要好很多。我讲讲倍增。
如果是暴力的话显然是从前往后一个一个枚举来计算。这里每次只往后移了一格,我们能不能一下子移很多格呢?
当然可以,我们可以用倍增的思想,第一次移1格,第二次移2格……如果再移就超过答案,就把移的格数除以2。如果最后移的格数是0,那么这一格就是答案
#include<cstdio>
#include<cctype>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; const int MAXN = + ;
int a[MAXN], s[MAXN], n, m, sum; void read(int& x)
{
int f = ; x = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -; ch = getchar(); }
while(isdigit(ch)) { x = x * + ch - ''; ch = getchar(); }
x *= f;
} int main()
{
read(n); read(m);
_for(i, , n) read(a[i]), s[i] = s[i-] + a[i];
while(m--)
{
int T; read(T);
int k = , p = , sum = ; //k为当前在哪一格,p为下一步要移多少格,sum为已经走了的格的总和
while(p)
{
if(k + p <= n && sum + s[k + p] - s[k] <= T)
{
sum += s[k + p] - s[k];
k += p;
p <<= ;
}
else p >>= ;
}
printf("%d\n", k);
}
return ;
}
hihocoder#1384
发现倍增的套路和二分有点像。出题就出来判断区间是否合法上
这里值得一提的是可以把新加进入的数组sort一遍,然后和之前已经
有序的数组做一次归并,而不用从头再来sort
//这个程序WA,目前还不知道为什么
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cmath>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;
typedef long long ll;
const int MAXN = 5e5 + 10;
int n, m, a[MAXN];
int b[MAXN], t[MAXN];
ll T;
inline void read(int& x)
{
int f = 1; x = 0; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
x *= f;
}
inline void readll(ll& x)
{
ll f = 1; x = 0; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
x *= f;
}
void merge_sort(int L, int R, int p)
{
_for(i, R + 1, R + p) b[i] = a[i];
sort(b + R + 1, b + R + p + 1);
int i = L, pos = L, j = R + 1;
while(i <= R || j <= R + p)
{
if(j > R + p || i <= R && a[i] < b[j]) t[pos++] = a[i++];
else t[pos++] = b[j++];
}
_for(i, L, R + p) a[i] = t[i];
}
bool check(int L, int R, int p)
{
merge_sort(L, R, p);
ll res = 0;
int l = L, r = R + p, tmp = m;
while(tmp--)
{
if(l >= r) break;
res += (a[r] - a[l]) * (a[r] - a[l]);
if(res > T) return false;
r--; l++;
}
return true;
}
int main()
{
int t; read(t);
while(t--)
{
read(n); read(m); readll(T);
_for(i, 1, n) read(a[i]);
int L = 1, R, ans = 0, p;
while(L <= n)
{
R = L; p = 1;
ans++;
while(p)
{
if(R + p <= n && check(L, R, p)) //
{
R += p;
p <<= 1;
}
else p >>= 1;
}
L = R + 1;
}
printf("%d\n", ans);
}
return 0;
}
RMQ算法模板 poj 3264(快速求区间最值,不支持修改)
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;
const int MAXN = 8e4;
const int MAXM = 30;
int dmin[MAXN][MAXM], dmax[MAXN][MAXM], a[MAXN], n, q;
void RMQ_init()
{
_for(i, 1, n) dmin[i][0] = dmax[i][0] = a[i];
for(int j = 1; (1 << j) <= n; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++)
{
dmax[i][j] = max(dmax[i][j-1], dmax[i + (1 << (j-1))][j-1]);
dmin[i][j] = min(dmin[i][j-1], dmin[i + (1 << (j-1))][j-1]);
}
}
int RMQ_ans(int l, int r)
{
int k = 0;
while((1 << (k + 1)) <= r - l + 1) k++;
return max(dmax[l][k], dmax[r - (1 << k) + 1][k]) - min(dmin[l][k], dmin[r - (1 << k) + 1][k]);
}
int main()
{
scanf("%d%d", &n, &q);
_for(i, 1, n) scanf("%d", &a[i]);
RMQ_init();
while(q--)
{
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", RMQ_ans(l, r));
}
return 0;
}
倍增算法总结 ( 含RMQ模板)的更多相关文章
- LCA倍增算法的错误与模板
先上我原来的错误的代码 type node=^link; link=record num:int64; next:node; end; var fa:..,..] of int64; dep:..] ...
- LCA上的RMQ模板算法
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...
- LCA(最近公共祖先)之倍增算法
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...
- LCA倍增算法
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...
- Poj 3264 Balanced Lineup RMQ模板
题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...
- 后缀数组的倍增算法(Prefix Doubling)
后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...
- [置顶] 小白学习KM算法详细总结--附上模板题hdu2255
KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...
- CodeForces #549 Div.2 ELynyrd Skynyrd 倍增算法
题目 这道题目实际上可以用动态规划来做. 对于每个区间,我们从右边边界,往左边走,如果能走n-1次,那说明以右边边界为起点存在一个题目中说的子链. 利用倍增算法,实际上倍增也是动态规划.f[i][j] ...
随机推荐
- 【hiho一下 第八周】状态压缩·一
[题目链接]:http://hihocoder.com/problemset/problem/1044 [题意] [题解] 设f[i][j]表示; 前i-1个位置已经决策完; 然后i-m+1..i这一 ...
- Maven Hibernate
1.使用maven管理Hibernate实现自动装配jar包 2.需要在配置文件pom.xml中引入 如:引入hibaernate5.2.11.Final版本的jar包,需要做如下配置: <!- ...
- [叁]Pomelo游戏server编程分享 之 server结构与配置分析
网络部署结构 我们先看一下Pomeloserver网络部署情况,直接上图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3RiaW56aQ==/font/ ...
- Gym 100418J Lucky tickets(数位dp)
题意:给定一个n.求区间[1, n]之间的全部的a的个数.a满足: a能整除 把a表示自身二进制以后1的个数 思路:题意非常绕.... 数位dp,对于全部可能的1的个数我们都dfs一次 对于某一个可 ...
- 为代码减负之<三>视图(SQL)
在设计数据库时为了降低数据冗余.一般都会依照三范式去设计,但有时我们在查询时须要通过一字段获取跟这 个字段相关联的好几个字段.可是他们又分布在不同的表中,这时候假设依照正常途径走的话须要同一时候查询好 ...
- [C++设计模式]observer 观察者模式
有这么一种松耦合的需求: 有一些类的对象对类A对象的状态变化非常感兴趣,不会改变类A的对象,也不会被类A的对象改变,想以一种较小的代价观察对类A对象状态变化. 以下的几种方式也能实现上述目的 (1)通 ...
- 用jquery ajax做的select菜单,选中的效果
//用server端语言赋值给js变量 var departmentId = '<%=提交的值 %>', deviceId='<%=提交的值 %>' $(fun ...
- 2016.02.25,英语,《Vocabulary Builder》Unit 02
ag:来自拉丁语do.go.lead.drive,an agenda是要做事情的清单,an agent是代表他们做事的人,同时也是为他人做事的机构.拉丁语litigare包括词根lit,即lawsui ...
- 2015.05.12,外语,读书笔记-《Word Power Made Easy》 15 “如何谈论不同人的特点” SESSION 45
TEASER PREVIEW 以-ous结尾的,描绘某人特点的词语包括: fawning(['fɔ:niŋ] adj.奉承的),servilely(['sә:vail] adj. 卑屈的, 奴隶的) ...
- NEU 1009 Happiness Hotel
1009: Happiness Hotel 时间限制: 1 Sec 内存限制: 128 MB提交: 173 解决: 19[提交][状态][讨论版] 题目描述 The life of Little ...