题目链接

本质是维护斜率递增序列。

用分块的方法就是把序列分成sqrt(n)块,每个块分别用一个vector维护递增序列。查询的时候遍历所有的块,同时维护当前最大斜率,二分找到每个块中比当前最大斜率大的那个点。修改的时候只需要修改点所在的那个块即可。复杂度$O(m\sqrt nlogn)$

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+;
int n,m,h[N],in[N],L[N],R[N],sqrtn,n2;
vector<db> v[]; int main() {
scanf("%d%d",&n,&m),sqrtn=sqrt(n+0.5);
for(int i=; i<=n; ++i)L[i]=-;
for(int i=; i<=n; ++i) {
in[i]=i/sqrtn;
if(!~L[in[i]])L[in[i]]=i;
R[in[i]]=i;
n2=max(n2,in[i]);
}
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
h[x]=y;
v[in[x]].clear();
for(int i=L[in[x]]; i<=R[in[x]]; ++i) {
db t=(db)h[i]/i;
if(v[in[x]].size()&&v[in[x]].back()>t)continue;
v[in[x]].push_back(t);
}
db mx=;
int ans=;
for(int i=; i<=n2; ++i) {
int j=upper_bound(v[i].begin(),v[i].end(),mx)-v[i].begin();
ans+=v[i].size()-j;
if(v[i].size())mx=max(mx,v[i].back());
}
printf("%d\n",ans);
}
return ;
}

用线段树的方法是利用“每个区间的递增序列长度为左区间的递增序列长度加上右区间中比左区间最大值大的递增序列长度”的性质来维护递增序列长度。左区间的递增序列长度可以直接加上,右区间的与左区间的最大值有关,姑且用$qry(mx[ls],rs)$来表示($mx[ls]$代表左区间最大值),则有区间合并公式:$cnt[u]=cnt[ls]+qry(mx[ls],rs)$。

然后就是$qry(mx[ls],rs)$的计算问题了。设$qry(x,u)$为区间u中比x大的部分的递增序列长度,则分两种情况讨论:

1)u的左区间最大值大于x,此时u的递增序列长度中位于右区间中的部分全部包含,因此$qry(x,u)=cnt[u]-cnt[ls]+qry(x,ls)$(注意不是$cnt[rs]+qry(x,rs)$,因为右区间中的部分序列会被左区间挡住)。

2)u的左区间最大值小于等于x,此时u的递增序列长度中位于左区间中的部分全部不包含,因此$qry(x,u)=qry(x,rs)$。

综上,只需要维护每个区间的最大值和递增序列长度,即可在$O(log^2n)$的时间内完成一次修改操作,而查询操作是$O(1)$的,因此总时间复杂度为$O(mlog^2n)$。

再一次体会到了区间分治的威力。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+;
int cnt[N<<],n,m;
db mx[N<<];
#define mid ((l+r)>>1)
#define ls (u<<1)
#define rs (u<<1|1)
int qry(db x,int u,int l,int r) {
if(mx[u]<=x)return ;
if(l==r)return cnt[u];
return mx[ls]>x?cnt[u]-cnt[ls]+qry(x,ls,l,mid):qry(x,rs,mid+,r);
}
void pu(int u,int l,int r) {
mx[u]=max(mx[ls],mx[rs]);
cnt[u]=cnt[ls]+qry(mx[ls],rs,mid+,r);
}
void upd(int p,db x,int u=,int l=,int r=n) {
if(l==r) {cnt[u]=,mx[u]=x; return;}
p<=mid?upd(p,x,ls,l,mid):upd(p,x,rs,mid+,r);
pu(u,l,r);
}
int main() {
scanf("%d%d",&n,&m);
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
upd(x,(db)y/x);
printf("%d\n",cnt[]);
}
return ;
}

BZOJ - 2957 (分块/线段树)的更多相关文章

  1. BZOJ 2141 分块 线段树

    思路: a[i] //By SiriusRen #include <cmath> #include <cstdio> #include <cstring> #inc ...

  2. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  3. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  4. bzoj 3585 mex - 线段树 - 分块 - 莫队算法

    Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...

  5. BZOJ5286 HNOI/AHOI2018转盘(分块/线段树)

    显然最优走法是先一直停在初始位置然后一次性走完一圈.将序列倍长后,相当于找一个长度为n的区间[l,l+n),使其中ti+l+n-1-i的最大值最小.容易发现ti-i>ti+n-(i+n),所以也 ...

  6. CDOJ 1157 数列(seq) 分块+线段树

    数列(seq) Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1157 Desc ...

  7. 【BZOJ 3476】 线段树===

    59  懒惰的奶牛贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位.贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北.正东.正西.正南这四个 ...

  8. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  9. CDOJ 1292 卿学姐种花 暴力 分块 线段树

    卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...

随机推荐

  1. NIO复习01

    NIO 概述: 1. Java NIO 由以下几个核心部分组成:Channels       Buffers           Selectors 2. 主要Channel的实现:FileChann ...

  2. 【Java】流与文件(端口 & 文件读写对象)

    概述: 1.input和output是相对于内存而言的.输入(input)就是写入到内存里,输出(output)就是把内存里的东西写到外面. 2.操作内存里的东西非常便利,要么声明变量,要么new对象 ...

  3. Django学习笔记之Django模版系统

    官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模板语言中有特 ...

  4. 20145201 实验四 Andoid开发基础

    20145201 实验四 Andoid开发基础 AndroidStudio安装 首先设置环境变量: Windows环境下Android Studio v1.0安装: 安装完毕. 运行Andriod S ...

  5. 【Java并发】Executor框架

      Executor框架简介 Java的线程既是工作单元,也是执行机制.从JDK5开始,把工作单元和执行机制分离开来. Executor框架由3大部分组成 任务. 被执行任务需要实现的接口:Runna ...

  6. spring security采用基于持久化 token 的方法实现的remember me功能

    采用该方法相较于简单加密方式安全一些.具体的原理见 http://wiki.jikexueyuan.com/project/spring-security/remember-me.html  一.建立 ...

  7. 《大型网站系统与JAVA中间件实践》读书笔记-数据访问层

    数据访问层 5.1.2数据库垂直/水平拆分的困难 随着网站业务的快速发展,数据量和访问量不断上升,数据库的压力越来越大. 更换更好的硬件(Scale Up)是一种解决方案,而且在我们能付得起硬件费用并 ...

  8. eclipse——反编译插件

    百度云链接 链接:https://pan.baidu.com/s/1iEtstiK5mJ4kDp6gTfVBww 密码:8wf7 在线安装地址 http://jd.benow.ca/jd-eclips ...

  9. JavaWeb -- Struts2 模型驱动

    1. 模型驱动 示例: 注册表单reg.jsp <%@ page language="java" contentType="text/html; charset=u ...

  10. thinkphp5新特性

    1.惰性加载(需要什么就加载什么,不需要什么就不加载),显著提高了应用性能: 2.支持composer: 3.遵守PSR-2.PSR-4规范: 4.支持单元测试: 5.安全机制,详细的日志能帮你轻轻松 ...