发现lca的倍增解法和st表差不多。。原理都是一样的

/*
整篇文章分成两部分,中间没有图片的部分,中间有图片的部分
分别用ST表求f1,f2表示以第i个单词开始,连续1<<j行能写多少单词
*/
#include<bits/stdc++.h>
#define FIN freopen("in.txt","r",stdin);
using namespace std;
#define ll long long
#define MX 100005
#define inf 0x3f3f3f3f
int mx,n,w,dw,pw,a[MX];
int f1[MX][],f2[MX][];
void ST(){
for(int i=;i<=n;i++){//只填一行的状态
int cnt=a[i],j=i+;
while(cnt+a[j]+<=w && j<=n) cnt+=a[j++]+;
f1[i][]=j-i;
}
for(int j=;(<<j)<=mx;j++)
for(int i=;i<=n;i++)
f1[i][j]=f1[i][j-]+f1[i+f1[i][j-]][j-]; for(int i=;i<=n;i++){
int cnt=,j=i,flag=;
while(cnt+a[j]+flag<=dw)//图片的左端能填入的单词
cnt+=a[j++]+flag,flag=;//填入第一个单词后下一个单词就要空一格了
int k=j;
cnt=flag=;
while(cnt+a[k]+flag<=w-pw-dw)//图片右端能填入的单词
cnt+=a[k++]+flag,flag=;
f2[i][]=k-i;
}
for(int j=;(<<j)<=mx;j++)
for(int i=;i<=n;i++)
if(f2[i][j-]==) f2[i][j]=;//第i个单词无法填入有图片的行
else f2[i][j]=f2[i][j-]+f2[i+f2[i][j-]][j-];
}
int RMQ1(int i,int x){//i是当前填的单词下标,x是可以填的行数,返回当前填到了第几个单词
if(x==) return i;
while(x && i<=n){
int j=;
while((<<(j+))<=x)j++;//先求出最大的j
i+=f1[i][j]; x-=(<<j);
}
return i;
}
int RMQ2(int i,int x){
if(x==) return i;
while(x && i<=n){
int j=;
while((<<(j+))<=x) j++;
i+=f2[i][j];x-=(<<j);
}
return i;
}
int RMQ3(int i){//返回填i-n个单词需要的行数
int ret=;
while(i<=n){
int j=;
while(i+f1[i][j+]<=n) j++;//找到最大的j
i+=f1[i][j];
ret+=(<<j);
}
return ret;
}
struct Query{
int x,h;
}q[MX];
int main(){
int T,m;
cin >> T;
while(T--){
scanf("%d%d%d%d",&n,&w,&pw,&dw);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
mx=n;
for(int i=;i<=m;i++) {
scanf("%d%d",&q[i].x,&q[i].h);
mx=max(mx,n+q[i].x+q[i].h);
}
ST();
for(int i=;i<=m;i++){
int x=q[i].x,h=q[i].h;
int tmp=RMQ3();//只用f1
if(tmp<=x-){
printf("%d\n",tmp+h);
continue;
}
int ans=x+h-;
int p=RMQ1(,x-);//从第一个单词开始连续x-1行能填的单词书
p=RMQ2(p,h);//从第p个单词开始连续h行能填的单词数
if (p<=n) ans+=RMQ3(p);//把剩下的单词填进去
printf("%d\n",ans);
}
}
return ;
}

hdu6107 倍增法st表的更多相关文章

  1. CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表

    传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...

  2. CF1190E Tokitsukaze and Explosion 二分、贪心、倍增、ST表

    传送门 最小值最大考虑二分答案,不难发现当最小值\(mid\)确定之后,原点到所有直线的距离一定都是\(mid\)时才是最优的,也就是说这些直线一定都是\(x^2+y^2=mid^2\)的切线. 接下 ...

  3. 倍增笔记ST表

    https://noip-1253948194.cos.ap-beijing.myqcloud.com/%E5%80%8D%E5%A2%9E-ST%E7%AE%97%E6%B3%95.mp4 1123 ...

  4. ST表学习笔记

    ST表是一种利用DP思想求解最值的倍增算法 ST表常用于解决RMQ问题,即求解区间最值问题 接下来以求最大值为例分步讲解一下ST表的建立过程: 1.定义 f[i][j]表示[i,i+2j-1]这个长度 ...

  5. BZOJ4556 [Tjoi2016&Heoi2016]字符串 【后缀数组 + 主席树 + 二分 + ST表】

    题目 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职 ...

  6. poj3264 倍增法(ST表)裸题

    打出st表的步骤:1:建立初始状态,2:区间按2的幂从小到大求出值 3:查询时按块查找即可 #include<iostream> #include<cstring> #incl ...

  7. P7599-[APIO2021]雨林跳跃【二分,倍增,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/P7599 题目大意 \(n\)棵树,在某棵树上时可以选择向左右两边第一棵比它高的树跳,现在\(q\)次询问从\([A ...

  8. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

  9. RMQ(倍增法求ST)

    解决什么问题:区间查询最值 倍增思想:每次得出结果的范围呈2的幂次增长,有人说相当于二分,目前我觉得相当于线段树的查找. 具体理解看代码: /*倍增法求ST*/ #include<math.h& ...

随机推荐

  1. item2乱码问题

    使用的是 mac 环境,本地使用终端打开中文可以正常显示,但是连接远端服务器上发现就编程乱码了,之前一直是好好的,但是突然有一天开始就乱码了,怀疑是我电脑升级后导致系统环境配置发生变化引起的.直接上解 ...

  2. 继承之es5对比es6

    es5: 熟悉es5的童鞋们就知道es5的继承多么恶心~~ es5最经典的继承写法就是如下这样 1.写一个function,用this来扩展其值类属性 2.prototype添加其方法类属性 3.若整 ...

  3. C#修饰符详解

    不定期更新,2017.8.9 一.new 别看new这个修饰符经常用,恐怕很多人都不知道其本质.我们先来看看new修饰符的官方定义: new 仅允许在嵌套类声明中使用,表明类中隐藏了由基类中继承而来的 ...

  4. javascript Date定义和体验

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. JavaScript 从入门到放弃(一)事件委托和使用innerHTML添加元素

    一.使用事件委托 一个简单的需求,比如想给ul下面的li加上点击事件,点击哪个li,就显示那个li的innerHTML.这个貌似很简单!代码如下! <!DOCTYPE html> < ...

  6. MySQL锁解决并发问题详解

    文章分为以下几个要点 问题描述以及解决过程 MySQL锁机制 数据库加锁分析 下面讨论的都是基于MySQL的InnoDB. 0. 问题描述以及解决过程 因为涉及到公司利益问题,所以下面很多代码和数据库 ...

  7. caffe 中 python 数据层

    caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. ...

  8. Linux之Ubuntu与Windows更改默认启动顺序[转载]

    装双系统后,经常会遇到与Windows更改默认启动顺序的需要,这样有助于开机时可以避免手动选择经常使用的系统了. 当然这解决办法不是博主的主意,本文纯属抄録者,故文章题目也声明了是转载,解决方案如下叙 ...

  9. luogu P4289 [HAOI2008]移动玩具

    传送门 这道题可以二进制记录状态搜索 也可以做以下考虑 若一个棋子要移动到另一个位置上去,则步数为两点的曼哈顿距离(横坐标差的绝对值+纵坐标差的绝对值),因为假设路径上有其他的棋子,可以通过移动其他棋 ...

  10. luogu P3978 [TJOI2015]概率论

    看着就是要打表找规律 使用以下代码 for(int i=3;i<=20;i++) { int a1=0,a2=0; for(int j=1;j<i;j++) { for(int k=0;k ...