题意:给个T,T组数据;

每组给个n,m;n个数,m个操作;

(对序列的操作是,一开始假设你手上东西是-INF,到i=1时拿起1,之后遍历,遇到比手头上的数量大的数时替换(拿到手的算拿走),问最后拿走几个)

每次操作是将p位变为q;问此时序列能拿走几个数;

思路:假设p位变了,不管变大变小,我们都得知道一件事,就是要找到在p之前最长的序列;

  因为这个是不变的,可以预处理,所以说我们就在第i位置记录1~i的最大值,和最大取走的数量以及最大数的id,这样就可以知道p-1位置的信息就是1~p-1位置最大的数的信息,O(1)得到;

  (如果q比1~p-1最大的数小,那么就将q变为那个最大的数,因为这样我们就可以不用分情况去查询)

  之后就是要找到比q大的第一个数,我是用线段树维护的,找比q大的第一个数的位置;找到了之后你就会希望能得到以这个数为起点的最大可取数量,那么我们就要计算出每个位置开始可以得到的最大数量;实现方法就是倒过来遍历那n个数,每次查询i~n里比a[i]大的第一个数的位置cnt,然后假设记录数组为dp,那么就是dp[i]=dp[cnt]+1;没找到的情况就令这个位置为1

以下是代码实现:

 #include<bits/stdc++.h>
#define mid ((node[now].l+node[now].r)>>1)
#define Max(a, b) (a>b?a:b)
using namespace std;
typedef long long ll;
const int N=1e5+, INF=0x3f3f3f3f, mod=;
int dp[N];
struct Node{
int num, id, len;
}maxn[N];
int sav[N];
struct No{
int ret;
struct no{
int l, r, maxn;
}node[N<<];
void build(int L, int R, int now){
node[now].l=L;
node[now].r=R;
if(L==R) node[now].maxn=sav[L];
else{
build(L, mid, now<<);
build(mid+, R, now<<^);
node[now].maxn=Max(node[now<<].maxn, node[now<<^].maxn);
}
}
void querymax(int v, int now, int L, int R){
if(node[now].l==node[now].r){
if(node[now].maxn>v) ret=min(ret, node[now].l);
return ;
}
if(node[now].r<=R&&node[now].l>=L){
if(node[now<<].maxn>v){
querymax(v, now<<, L, R);
}else{
querymax(v, now<<^, L, R);
}
return ;
}
if(L<=mid)
querymax(v, now<<, L, R);
if(R>mid)
querymax(v, now<<^, L, R);
}
}tree;
int main( ){
int T, m, n, p, q;
register int i, j, k, ans, cnt, sav1;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(i=; i<=n; ++i){
scanf("%d", sav+i);
if(maxn[i-].num<sav[i]){
maxn[i].num=sav[i];
maxn[i].id=i;
maxn[i].len=maxn[i-].len+;
}else{
maxn[i]=maxn[i-];
}
dp[i]=;
}
tree.build(, n, );
for(i=n; i>; --i){
tree.ret=n+;
tree.querymax(sav[i], , i, n);
cnt=tree.ret;
if(cnt>n)
cnt=;
dp[i]=dp[cnt]+;
}
while(m--){
sav1=ans=;
scanf("%d%d", &p, &q);
if(p==){
tree.ret=n+;
tree.querymax(q, , p+, n);
cnt=tree.ret;
if(cnt<=n) printf("%d\n", dp[cnt]+);
else puts("");
continue;
}
ans=maxn[p-].len;
if(q>maxn[p-].num){
++ans;
}else{
q=maxn[p-].num;
}
tree.ret=n+;
tree.querymax(q, , p+, n);
cnt=tree.ret;
if(cnt<=n)
ans+=dp[cnt];
printf("%d\n", ans);
}
}
}

拙略的代码

HDU 6406 Taotao Picks Apples 线段树维护的更多相关文章

  1. hdu 6406 Taotao Picks Apples 线段树 单点更新

    Taotao Picks Apples Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Ot ...

  2. hdu 6406 Taotao Picks Apples (线段树)

    Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n apples o ...

  3. [乱搞]hdu 6406 Taotao picks apples 笛卡尔树+倍增

    题目链接 Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n app ...

  4. HDU 6406 Taotao Picks Apples & FJUT3592 做完其他题后才能做的题(线段树)题解

    题意(FJUT翻译HDU): 钱陶陶家门前有一棵苹果树. 秋天来了,树上的n个苹果成熟了,淘淘会去采摘这些苹果. 到园子里摘苹果时,淘淘将这些苹果从第一个苹果扫到最后一个. 如果当前的苹果是第一个苹果 ...

  5. hdu 6406 Taotao Picks Apples (2018 Multi-University Training Contest 8 1010)(二分,前缀和)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6406 思路: 暴力,预处理三个前缀和:[1,n]桃子会被摘掉,1到当前点的最大值,1到当前点被摘掉的桃子的 ...

  6. HDU - 6406 Taotao Picks Apples (RMQ+dp+二分)

    题意:N个高度为hi的果子,摘果子的个数是从位置1开始从左到右的严格递增子序列的个数.有M次操作,每次操作对初始序列修改位置p的果子高度为q.每次操作后输出修改后能摘到得数目. 分析:将序列分为左.右 ...

  7. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  8. hdu6406 Taotao Picks Apples(线段树)

    Taotao Picks Apples 题目传送门 解题思路 建立一颗线段树,维护当前区间内的最大值maxx和可摘取的苹果数num.最大值很容易维护,主要是可摘取的苹果数怎么合并.合并左右孩子时,左孩 ...

  9. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

随机推荐

  1. 11.19daily_scrum

    本阶段的工作内容为测试并且撰写笔记本APP应用的测试报告,目的在于总结测试阶段的测试以及分析测试结果,描述系统是否符合需求,测试软件功能的完善性.除了音频界面还未完成,其他部分均已开始实现测试功能,具 ...

  2. Day Two

    站立式会议 站立式会议内容总结 442 完成了计划列表和toolbar的事件监听部分 遇到问题:父组无法实现事件监听,只能实现点击折叠.展开的功能. 331 学习form中list数据添加 遇到的问题 ...

  3. Daily Scrum - 11/26

    Meeting Minutes 今天是Sprint 3第一天,任烁向我们交代了他那边的代码情况,他这两天回学校有点事,人千和章玮暂时先熟悉一下他写的那部分,正在试图将代码merge起来.重阳实现了进度 ...

  4. VS2013安装及测试

    一.Visual Studio的安装 首先是Visual Studio英文版的安装,安装完成后,为了用的时候方便,我从官网下载Visual Studio 2013的语言包并安装. 二.进行单元测试. ...

  5. Alpha冲刺第4天

    Alpha第四天 1.团队成员 郑西坤 031602542 (队长) 陈俊杰 031602504 陈顺兴 031602505 张胜男 031602540 廖钰萍 031602323 雷光游 03160 ...

  6. d3 数学方法(伪随机数生成器 )

    一.正态(高斯)分布(normal (Gaussian) distribution)的随机数 /* var nomarlRandmo = d3.random.normal(); console.log ...

  7. Ubuntu17安装Jenkins

    Java安装 Jenkins基于Java, 所以需要先安装java. Linux下安装java只要配置java环境变量即可. 首先,解压java到相应目录,我一般习惯把安装的软件放到目录/usr/lo ...

  8. Django时间时区问题(received a naive datetime while time zone support is active)

    在django1.4以后,存在两个概念 naive time 与 active time. 简单点讲,naive time就是不带时区的时间,Active time就是带时区的时间. 举例来说,使用d ...

  9. mysql8.0+修改用户密码

    查看初始安装密码登陆: [root@VM_133_71_centos yum.repos.d]# cat /var/log/mysqld.log|grep 'A temporary password' ...

  10. 【Revit API】创建相机视角

    在Revit中有一个相机功能可以以相机视角产生一个视图.一开始我在Revit2016的API文档中找关键词Camera,但是没什么收获. 其实这个相机功能的真正核心是创建透视视图:View3D.Cre ...