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的更多相关文章

  1. CF765F Souvenirs 解题报告

    CF765F Souvenirs 题意翻译 给出\(n(2 \le n \le 10^5 )\) ,一个长为\(n\)的序列\(a(0 \le a_i \le 10^9 )\). 给出\(m(1\le ...

  2. CF765F Souvenirs 离线+线段树+主席树

    $ \color{#0066ff}{ 题目描述 }$ A县旁,连绵着一条长度为 n 的山脉,这条山脉由 n 座山峰组成,第 i 座山 峰的高度为 ai.作为著名的旅游县城,每天来到山脉游玩的旅客络绎不 ...

  3. 多校联训 DS 专题

    CF1039D You Are Given a Tree 容易发现,当 \(k\) 不断增大时,答案不断减小,且 \(k\) 的答案不超过 \(\lfloor\frac {n}{k}\rfloor\) ...

  4. 【CF765F】Souvenirs 主席树

    [CF765F]Souvenirs 题意:给你一个长度为n的序列{ai},有m个询问,每次询问给出l,r,问在所有$l\le x < y\le r$中,$|a_x-a_y|$的最小值是多少. $ ...

  5. 【CF765F】Souvenirs

    [CF765F]Souvenirs 题面 洛谷 题解 我们可以发现,对于某个右端点\(i\),左端点\(j\)在由\(i\rightarrow 1\)的过程中,每一段的答案是单调不增的,由这个性质,我 ...

  6. [HDU 2126] Buy the souvenirs (动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 题意:给你n个物品,m元钱,问你最多能买个多少物品,并且有多少种解决方案. 一开始想到的是,先解 ...

  7. HDU 2126 Buy the souvenirs (01背包,输出方案数)

    题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...

  8. HDU 2126 (背包方法数) Buy the souvenirs

    DP还有很长很长一段路要走.. 题意:给出n纪念品的价格和钱数m,问最多能买多少件纪念品和买这些数量的纪念品的方案数. 首先,求能买最多的纪念品的数量,用贪心法可以解决.将价钱排序,然后从最便宜的开始 ...

  9. HDU-2126 Buy the souvenirs

    数组01背包. http://acm.hdu.edu.cn/showproblem.php?pid=2126 http://blog.csdn.net/crazy_ac/article/details ...

随机推荐

  1. IPD体系向敏捷开发模式转型实施成功的四个关键因素

    文/杨学明  集成产品开发(IPD).集成能力成熟度模型(CMMI).敏捷开发(Agile Development)是当前国内外企业产品研发管理的最常用的3种模式.随着创新环境的快速发展,许多企业都会 ...

  2. Linux中逻辑卷的快照与还原

    有关逻辑卷的其他操作,请看: Linux中对逻辑卷的建立 Linux中对逻辑卷进行扩容与缩小 Linux中对逻辑卷的移除 LVM还有快照的功能,类似windows的系统还原点.其特点: 1.快照卷的容 ...

  3. 获取spring security用户相关信息

    在JSP中获得 使用spring security的标签库 在页面中引入标签 <%@ taglib prefix="sec" uri="http://www.spr ...

  4. SQLServer的三种Recovery Model

    SQL Server恢复模式的三种类型的比较 此文章主要向大家讲述的是SQL Server恢复模式,我们主要介绍的是三种恢复模式,其中包括简单SQL Server数据库的恢复模式.完整恢复模式与大容量 ...

  5. Jenkins自动化部署-----持续交付【转】

    感谢之前带领过我的leader,让我能够知道什么是好的开发方法. 在很早之前就接触过敏捷开发.什么是敏捷开发,简单来说就是让软件可靠地,快速地发布出来的一种开发方法和技巧. 而敏捷开发中有许多的实践, ...

  6. Zookeeper与Kafka基础概念和原理

    1.zookeeper概念介绍 在介绍ZooKeeper之前,先来介绍一下分布式协调技术,所谓分布式协调技术主要是用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种共享资源,防止造成 ...

  7. QQ的孤独

    接触网络到现在,已是好多年前的事了.初识网络犹如初恋般,充满了新鲜和好奇,于是,从聊天室到QQ,MSN,邮箱,再去BBS.然后有了博客^^^^^^ 那时的网络于我是那般充满诱惑,整天穿梭其中,乐此不彼 ...

  8. 转://11g之后,通过v$wait_chains视图诊断数据库hang和Contention

    1g之前,通常我们数据库hang住了之后,我们会对数据库做hang analyze来进行分析,在11g之后,我们可以通过一个新的视图v$wait_chains来诊断数据库hang和contention ...

  9. zabbix proxy部署

    一.概述 环境: 因为公司需要监控远程客户机,但server端无法主动连接agent端,客户端可以连接公司ip 公司有固定ip,可以开放某个端口给zabbixserver,客户机agent端可以主动通 ...

  10. 【Git】+ 新建+删除+上传+覆盖

    上传代码时邮箱格式不符合:https://blog.csdn.net/u012558695/article/details/64921922 在本地新建一个分支: git branch newBran ...