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. 20180831-Linux环境下Python 3.6.6 的安装说明

    20180831-Linux环境下Python 3.6.6 的安装说明 摘要:Python3 安装部署,普通用户,编译安装 Author: andy_yhm@yeah.net Date: 201808 ...

  2. sqlserver数据库触发器调用外部exe

    sqlserver数据库触发器调用外部exe,同事可以选择参入参数! sqlserver使用 master..xp_cmdshell 进行外部exe的执行. 使用master..xp_cmdshell ...

  3. UITableView编辑模式大全解

    1.UITableView 的编辑模式 进入编辑模式 代码体现 // 设置 editing 属性 tableView?.editing = true // 这个设置的时候是有动画效果的 tableVi ...

  4. python 完整项目开发流程

    1. 安装 python    2. 安装virtualenvwrapper    3. 虚拟环境相关操作    4. 进入虚拟环境, 安装django    5. 安装编辑器    6. 安装mys ...

  5. 如何在Spring Data JPA中引入Querydsl

    一.环境说明 基础框架采用Spring Boot.Spring Data JPA.Hibernate.在动态查询中,有一种方式是采用Querydsl的方式. 二.具体配置 1.在pom.xml中,引入 ...

  6. 模拟vue的tag属性,在react里实现自定义Link

    我封装了一个简单的实现react里自定义Link的方法,方便大家使用. 因为普通组件没有metch.location.history等属性.只有在<Router>里面的<compon ...

  7. Jetson TX2(2)ubutu1604--安装opencv3.4.0

    1安装OpenCV3.4.0+contrib 1 在终端中敲入以下两句sudo rm /var/cache/apt/archives/locksudo rm /var/lib/dpkg/lock su ...

  8. Golang 入门 : 字符串

    在 Golang 中,字符串是一种基本类型,这一点和 C 语言不同.C 语言没有原生的字符串类型,而是使用字符数组来表示字符串,并以字符指针来传递字符串.Golang 中的字符串是一个不可改变的 UT ...

  9. sass的使用

    1.声明变量-全局声明-局部声明 中划线或下划线两种用法相互兼容  $nav-color: #F90; $highlight-border: 1px solid $nav-color;  nav{ $ ...

  10. 定时任务 cron命令

    一名linux新手,因为项目需要现在在学习linux操作系统. 因项目需要做一个定时任务,每个小时访问某一个url一次,通过参考很多大神的博客学会了crontab命令的使用方法 crontab -u ...