博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[CF765F]Souvenirs
阅读量:6824 次
发布时间:2019-06-26

本文共 2159 字,大约阅读时间需要 7 分钟。

[CF765F]Souvenirs

题目大意:

给定一个长度为\(n(n\le2\times10^5)\)的数列\(A_{1\sim n}\)\(m(m\le3\times10^5)\)次询问,每次询问区间\([l,r]\)内两个不相等的数之差的最小值。

思路:

将所有询问离线,按右端点排序。

枚举右端点\(r\),用线段树维护对于当前的右端点,每个左端点对应的答案。

线段树每个结点维护对应区间归并排序后的状态,即构造一棵归并树。

插入新的右端点就相当于在线段树对应区间找到最接近的数,然后更新答案。

显然暴力更新的复杂度在最坏情况下是单次\(\mathcal O(n)\)的。

发现由于右端点固定,若左边的答案已经不会比右边优,则左端点已经没有更新的必要。先更新右子区间,再更新左子区间剪枝即可。

时间复杂度\(\mathcal O(m\log^2 n)\)

源代码:

#include
#include
#include
#include
#include
inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x;}const int N=2e5+1,M=3e5;int a[N],ans[M],min;struct Query { int l,r,id; bool operator < (const Query &rhs) const { return r
>1 #define mid ((b+e)>>1) private: int val[N<<2]; std::vector
v[N<<2]; public: void build(const int &p,const int &b,const int &e) { val[p]=INT_MAX; if(b==e) { v[p].push_back(a[b]); return; } build(p _left,b,mid); build(p _right,mid+1,e); v[p].resize(e-b+1); std::merge(v[p _left].begin(),v[p _left].end(),v[p _right].begin(),v[p _right].end(),v[p].begin()); } void modify(const int &p,const int &b,const int &e,const int &r,const int &x) { if(r==e) { auto it=std::lower_bound(v[p].begin(),v[p].end(),x); if(it
=v[p].begin()) val[p]=std::min(val[p],std::abs(x-*it)); if(val[p]>=min) return; if(b==e) { min=val[p]; return; } } if(r>mid) modify(p _right,mid+1,e,r,x); modify(p _left,b,mid,std::min(mid,r),x); val[p]=std::min(val[p _left],val[p _right]); min=std::min(min,val[p]); } int query(const int &p,const int &b,const int &e,const int &l,const int &r) const { if(b==l&&e==r) return val[p]; int ret=INT_MAX; if(l<=mid) ret=std::min(ret,query(p _left,b,mid,l,std::min(mid,r))); if(r>mid) ret=std::min(ret,query(p _right,mid+1,e,std::max(mid+1,l),r)); return ret; } #undef _left #undef _right #undef _par #undef mid};SegmentTree t;int main() { const int n=getint(); for(register int i=1;i<=n;i++) a[i]=getint(); const int m=getint(); for(register int i=0;i

转载于:https://www.cnblogs.com/skylee03/p/9484014.html

你可能感兴趣的文章
ET120以太网环回器介绍
查看>>
ActiveMQ快速入门
查看>>
java自学篇之程序设计基础
查看>>
swiper的基础使用(五)
查看>>
Windows Server 2012R2 Hyper-v之虚拟机复制(2)
查看>>
大数据各种实用网站
查看>>
win7安装laravel
查看>>
Oracle 各后台进程功能说明
查看>>
屏蔽storm ui的kill功能
查看>>
我的友情链接
查看>>
Oracle Decode函数的使用
查看>>
MSF学习笔记
查看>>
经典脚本案例--check memory
查看>>
20.31 expect脚本同步文件;20.32 expect脚本指定host和要同步的文件;20.33 构建文件分发系统;20.34...
查看>>
CentOS单用户与救援模式
查看>>
postfix 源码centos7上搭建及错误提示---亲测
查看>>
【Redis篇】Redis集群安装与初始
查看>>
jquery基础
查看>>
C# 集合已修改;可能无法执行枚举操作
查看>>
FSM Code Generator
查看>>