题目链接

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

用分块的方法就是把序列分成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. Spring4.2.3+Hibernate4.3.11整合( IntelliJ maven项目)(使用Annotation注解)(Junit测试类)

    1. 在IntelliJ中新建maven项目 给出一个建好的示例 2. 在pom.xml中配置依赖 包括: spring-context spring-orm hibernate-core mysql ...

  2. poj1694

    /*给出一棵树的描述 第一行输入t,代表案例的个数 第二行一个n代表这棵树有n个节点 接下来n行第一个数是节点的编号,根节点编号为1,然后第二个数是节点的个数,如果为0那就没子节点,否则输入节点的 编 ...

  3. xshell 常用命令

    一.grep 命令 (1)命令格式 grep [选项] pattern [file] (2)常用参数 参数 描述 -c 计算找到 '搜寻字符串'(即 pattern) 的次数 -i 忽略大小写的不同, ...

  4. Parameter Binding in ASP.NET Web API

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding ...

  5. Redis 后台运行

    编辑配置文件 vim {redis_home}/redis.conf 修改daemonize  (默认为no,修改为yes) 启动redis{redis_home}/src/redis-server ...

  6. 重装window 7系统,从做一个u盘启动盘,到装系统,很不错

    老毛桃U盘启动盘制作工具是现在最流行的U盘装系统和维护电脑的专用工具,一是制作简单,几乎100%支持所有U盘一键制作为启动盘,不必顾虑以前量产U盘考虑专用工具的问题.二是制作后工具功能强大,支持GHO ...

  7. eclipse格式化代码快捷键失效解决的一个基本方法

    eclipse格式化代码的快捷键Ctrl+Shift+F,是比较常用的一个快捷键之一. 但是用到时却发现按了也没有反应,百度了说是跟搜狗输入法的快捷键冲突了. 搜狗输入法的快捷键Ctrl+Shift+ ...

  8. CentOS 5 上使用yum同时安装32位和64位包的解决方法

    在centos上使用yum在线安装软件包的时候,有时候会同时安装32位和64位的包.并且在update的时候也会更新双份. 其实让yum只安装64位的包,只要在 /etc/yum.conf 中加个 e ...

  9. Springboot- Spring缓存抽象学习笔记

    Spring缓存作用准备: 1.准备数据(准备一个有数据的库和表/导入数据库文件,准备好表和表里面的数据) 2.创建javaBean封装数据 3.整合MyBatis操作数据库( 这里用MyBatis) ...

  10. 【C#笔札】 界面逐渐显现的实现

    如果labview做 就如同上图,so eazy! 现改C#实现这个简单的功能. 在工具箱找到Timer控件 双击 思路如下,界面打开时触发timer事件,每隔一段时间调整界面透明度 开搞 属性框中的 ...