CF765F Souvenirs
【CF765F】Souvenirs 主席树 - CQzhangyu - 博客园
其实不用主席树
感觉像是离线问题
但是不能支持差分。分治又处理不了
考虑按照右端点排序,线段树维护左端点为i的时候的答案
然后trick一下,把求ansl,变成求min(ansl....ansr),这样可以少更新很多
先把|ai-aj|变成j<i,aj>=ai这样找,然后再反过来做一次。
新加入的a[i],找之前第一个大于a[i]的a[pos],(pos是所在位置)
在pos位置更新答案。
对于k<pos,若a[k]>=a[pos],显然再和a[i]做贡献没有意义了。取到ansk一定能取到anspos
设mid=(a[pos]+a[i])/2,发现,对于k<pos,且a[k]>mid,a[k]和a[pos]做贡献一定更优(这在反过来的时候会考虑到),并且取到ansk一定能取到和pos做的贡献
所以只用考虑k<=mid,规模每次/2,log(max{ai})次logn
找pos,可以用动态开点线段树,每次找权值范围内最晚出现的。
复杂度:O(nlognlogai)
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=4e5+;
const int inf=0x3f3f3f3f;
int n,m;
int ans[N];
int a[N];
struct que{
int l,r,id;
}q[N];
bool cmp1(que a,que b){
return a.r<b.r;
}
bool cmp2(que a,que b){
return a.l>b.l;
} #define mid ((l+r)>>1)
namespace tr1{
int rt;
struct node{
int ls,rs;
int tim;
node(){
tim=;
}
}t[N*];
int tot;
void pushup(int x){
t[x].tim=max(t[t[x].ls].tim,t[t[x].rs].tim);
}
int fin(int x,int l,int r,int L,int R){
if(L>R) return ;
if(!x) return ;
if(L<=l&&r<=R){
if(l==r) return t[x].tim;
if(t[t[x].ls].tim>t[t[x].rs].tim) return fin(t[x].ls,l,mid,L,R);
else return fin(t[x].rs,mid+,r,L,R);
}
if(R<=mid) return fin(t[x].ls,l,mid,L,R);
if(L>mid) return fin(t[x].rs,mid+,r,L,R);
return max(fin(t[x].ls,l,mid,L,R),fin(t[x].rs,mid+,r,L,R));
}
void chan(int &x,int l,int r,int p,int ti){
if(!x) x=++tot;
if(l==r){
t[x].tim=max(t[x].tim,ti);return;
}
if(p<=mid) chan(t[x].ls,l,mid,p,ti);
else chan(t[x].rs,mid+,r,p,ti);
pushup(x);
}
void init(){
t[].tim=;
tot=;
}
void clear(){
for(reg i=;i<=tot;++i){
t[i].ls=t[i].rs=;
t[i].tim=;
}
tot=;rt=;
} }
namespace tr2{
#define ls (x<<1)
#define rs (x<<1|1)
int ans[*N];
void build(int x,int l,int r){
if(l==r){
ans[x]=inf;return ;
}
ans[x]=inf;
build(x<<,l,mid);build(x<<|,mid+,r);
}
void pushup(int x){
ans[x]=min(ans[ls],ans[rs]);
}
void upda(int x,int l,int r,int p,int c){
if(l==r){
ans[x]=min(ans[x],c);return;
}
if(p<=mid) upda(ls,l,mid,p,c);
else upda(rs,mid+,r,p,c);
pushup(x);
}
int query(int x,int l,int r,int L,int R){
if(L<=l&&r<=R) return ans[x];
if(R<=mid) return query(ls,l,mid,L,R);
if(L>mid) return query(rs,mid+,r,L,R);
return min(query(ls,l,mid,L,R),query(rs,mid+,r,L,R));
}
void clear(){
memset(ans,0x3f,sizeof ans);
} } int main(){
// cout<<" 23333 "<<endl;
rd(n);
int lim=;
for(reg i=;i<=n;++i) rd(a[i]),lim=max(lim,a[i]);
// cout<<" after rd "<<lim<<endl;
rd(m);
for(reg i=;i<=m;++i){
rd(q[i].l);rd(q[i].r);q[i].id=i;
}
// cout<<" after rd "<<endl;
memset(ans,0x3f,sizeof ans);
sort(q+,q+m+,cmp1);
int ptr=;
// cout<<" sort1 "<<endl;
tr2::build(,,n);
tr1::init();
// cout<<" built "<<endl; for(reg i=;i<=n;++i){
// cout<<" ii "<<i<<" ptr "<<ptr<<endl;
if(i!=){
int pos=tr1::fin(tr1::rt,,lim,a[i],lim);
while(pos){
// cout<<" pos "<<pos<<endl;
tr2::upda(,,n,pos,a[pos]-a[i]);
// cout<<" after tr2 upda "<<endl;
pos=tr1::fin(tr1::rt,,lim,a[i],min(a[pos]-,(a[pos]+a[i])/));
}
}
// cout<<" over udpa "<<endl;
while(ptr<=m&&q[ptr].r==i){
ans[q[ptr].id]=min(ans[q[ptr].id],tr2::query(,,n,q[ptr].l,i));
++ptr;
}
tr1::chan(tr1::rt,,lim,a[i],i);
}
// cout<<" turn1 "<<endl; tr2::clear();
tr1::clear();
tr2::build(,,n); sort(q+,q+m+,cmp2);
ptr=;
// cout<<" st2 "<<endl;
for(reg i=n;i>=;--i){
if(i!=n){
int pos=tr1::fin(tr1::rt,,lim,a[i],lim);
while(pos){
pos=n-pos+;
tr2::upda(,,n,pos,a[pos]-a[i]);
pos=tr1::fin(tr1::rt,,lim,a[i],min(a[pos]-,(a[pos]+a[i])/));
}
}
while(ptr<=m&&q[ptr].l==i){
ans[q[ptr].id]=min(ans[q[ptr].id],tr2::query(,,n,i,q[ptr].r));
++ptr;
}
tr1::chan(tr1::rt,,lim,a[i],n-i+);
}
// cout<<" turn2 "<<endl;
// return 0;
for(reg i=;i<=m;++i){
printf("%d\n",ans[i]);
}
return ;
} }
signed main(){
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
CF765F Souvenirs的更多相关文章
- CF765F Souvenirs 解题报告
CF765F Souvenirs 题意翻译 给出\(n(2 \le n \le 10^5 )\) ,一个长为\(n\)的序列\(a(0 \le a_i \le 10^9 )\). 给出\(m(1\le ...
- CF765F Souvenirs 离线+线段树+主席树
$ \color{#0066ff}{ 题目描述 }$ A县旁,连绵着一条长度为 n 的山脉,这条山脉由 n 座山峰组成,第 i 座山 峰的高度为 ai.作为著名的旅游县城,每天来到山脉游玩的旅客络绎不 ...
- 多校联训 DS 专题
CF1039D You Are Given a Tree 容易发现,当 \(k\) 不断增大时,答案不断减小,且 \(k\) 的答案不超过 \(\lfloor\frac {n}{k}\rfloor\) ...
- 【CF765F】Souvenirs 主席树
[CF765F]Souvenirs 题意:给你一个长度为n的序列{ai},有m个询问,每次询问给出l,r,问在所有$l\le x < y\le r$中,$|a_x-a_y|$的最小值是多少. $ ...
- 【CF765F】Souvenirs
[CF765F]Souvenirs 题面 洛谷 题解 我们可以发现,对于某个右端点\(i\),左端点\(j\)在由\(i\rightarrow 1\)的过程中,每一段的答案是单调不增的,由这个性质,我 ...
- [HDU 2126] Buy the souvenirs (动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解 ...
- HDU 2126 Buy the souvenirs (01背包,输出方案数)
题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...
- HDU 2126 (背包方法数) Buy the souvenirs
DP还有很长很长一段路要走.. 题意:给出n纪念品的价格和钱数m,问最多能买多少件纪念品和买这些数量的纪念品的方案数. 首先,求能买最多的纪念品的数量,用贪心法可以解决.将价钱排序,然后从最便宜的开始 ...
- HDU-2126 Buy the souvenirs
数组01背包. http://acm.hdu.edu.cn/showproblem.php?pid=2126 http://blog.csdn.net/crazy_ac/article/details ...
随机推荐
- PHP实现开心消消乐的算法示例
本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享PHP教程出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.需求描述: 1.在一个8*8的矩阵方格中随机 ...
- Linux内存描述之内存区域zone--Linux内存管理(三)
1 内存管理域zone 为了支持NUMA模型,也即CPU对不同内存单元的访问时间可能不同,此时系统的物理内存被划分为几个节点(node), 一个node对应一个内存簇bank,即每个内存簇被认为是一个 ...
- CentOS7中利用Xshell6向虚拟机本地上传文件
环境交代 Linux系统:CentOS7, Xshell版本:6 操作步骤 下面我们以一个文件上传来演示用法 第一步 建立连接,这里不多说 在Xshell中点击如下图标,或者直接按 Alt+Ctrl+ ...
- 进程命令(tasklist)
TaskList命令: // 描述: 显示本地或远程计算机上正在运行的进程列表信息. // 语法: tasklist [/s <computer> [ /u [<domain> ...
- Django REST framework基础:认证、权限、限制
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
- 使用opencv进行简单的手势检测[by Python]
代码参考于:https://github.com/rainyear/lolita/issues/8 简单的手势识别,基本思路是基于皮肤检测,皮肤的颜色在HSV颜色空间下与周围环境的区分度更高,从RGB ...
- WEB框架-Django组件学习-分页器学习
1.分页器基础学习 1.1 补充知识-批量创建 数据库中数据批量创建,不要每创建一个就往数据库中塞一个,会造成撞库,造成大量I/O操作,速速较慢,应该采用一次性创建大量数据,一次性将大量数据塞入到数据 ...
- day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象
迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...
- Linux实战教学笔记51:Zabbix监控平台3.2.4(三)生产环境案例
https://www.cnblogs.com/chensiqiqi/p/9162986.html 一,Zabbix生产环境监测案例概述 1.1 项目规划 [x] :主机分组 交换机 Nginx To ...
- (四)Exploring Your Cluster
The REST API Now that we have our node (and cluster) up and running, the next step is to understand ...