题目链接

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

用分块的方法就是把序列分成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. Linux中read命令的用法—(6/30)

    read命令是一个非常重要的bash命令,用于从键盘或者表中输入中文本,并且可以和用户进行交互:该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开.在read命令后面,如果没有指定变量名 ...

  2. [ufldl]Supervised Neural Networks

    要实现的部分为:forward prop, softmax函数的cost function,每一层的gradient,以及penalty cost和gradient. forwad prop forw ...

  3. 详解Linux系统中的文件名和文件种类以及文件权限

    Linux文件种类与副文件名 一直强调一个概念,那就是:任何装置在Linux底下都是文件, 不仅如此,连资料沟通的介面也有专属的文件在负责-所以,你会瞭解到,Linux的文件种类真的很多- 除了前面提 ...

  4. 不可忽视的技术趋势:Blockchain

    提到blockchain,估计很多人还很陌生,但是提到比特币,很多人就会"哦!就是那个大骗局!"... 比特币的未来搁置不谈(我也不看好).但是比特币的技术基础:blockchai ...

  5. Samba的安装配置使用

    ////////////////////////////////Samba//////////////////////////////////////////// 小常识:在同一局域网中,两个系统的工 ...

  6. django Models 常用的字段和参数

    1.字段 CharField IntegerField floatField DateTimeField DateField DecimalField 2.参数 null default choice ...

  7. js进阶---12-10、jquery绑定事件和解绑事件是什么

    js进阶---12-10.jquery绑定事件和解绑事件是什么 一.总结 一句话总结:on和off. 1.jquery如何给元素绑定事件? on方法 22 $('#btn1').on('click', ...

  8. CodeForces - 767C

    花了6个小时,终于成功ac...... 两边dfs,第一遍求子树和,第二遍判断有没有2*t[s]/3和t[s]/3,因为要求的节点可能是在同一条线上,同时要有2*t[s]/3和t[s]/3的情况,且2 ...

  9. 编译android源码中的icu4c

    在external/icu4c/studata/readme.txt,里面有修改icu4c中资源的编译方法 # 具体步骤(可复制下面命令,直接运行): # 1)新增或者修改external/icu4c ...

  10. IOS-导航路线

    1.可以将需要导航的位置丢给系统自带的APP进行导航 2.发送网络请求到公司服务器获取导航数据, 然后自己手动绘制导航 3.利用三方SDK实现导航(百度) >当点击开始导航时获取用户输入的起点和 ...