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. 测者的测试技术笔记:揭开java method的一个秘密--巨型函数

    相信,很多人都不知道Java的Method的上限为64K.本文将超过这个上限的函数叫做巨型函数. 巨型函数的问题 1.如果代码超过了这个限制,Java编译器就报"Code too large ...

  2. Spark之Yarn提交模式

    一.Client模式 提交命令: ./spark-submit --master yarn --class org.apache.examples.SparkPi ../lib/spark-examp ...

  3. MongoDB在已有账号的实例下还原数据库报错的分析(error applying oplog)

    一. 背景 今天在MongoDB 4.0.4版本下,在还原恢复数据库时报错. 主要错误为: Failed: restore error: error applying oplog: applyOps: ...

  4. Python编写脚本(输出三星形状的‘*’符号)

    环境:python3.* 心得:个人认为脚本非我强项,以下效果可以有更简单解决方案,纯属练习逻辑. 方案一: s=1 while s<=10: #这是决定多少列,起始为1,大循环一圈即加一,就是 ...

  5. win10 anaconda+tensorflow+keras

    最近想用python实现下lstm模型,然后看网上教程配置了下环境,中间出现了一些问题,记录下. 1.开始menu中anaconda文件夹下没有ipython的图标了. 我电脑里的anaconda是很 ...

  6. Python基础——5模块

    使用模块 ‘the first line is zhushi’ _author_ = ‘syz’ import sys def test(): args = sys.argv if len(args) ...

  7. 好程序员分享ApacheSpark常见的三大误解

    误解一:Spark是一种内存技术 大家对Spark最大的误解就是其是一种内存技术(in-memorytechnology).其实不是这样的!没有一个Spark开发者正式说明这个,这是对Spark计算过 ...

  8. Strem_01

    import 'package:flutter/material.dart';import 'dart:async';import 'dart:ui'; void main()=>runApp( ...

  9. shell 脚本中执行sql

    #!/bin/bashsql='show databases' result=`mysql -uroot -pengine2user -h127.0.0.1 -e "${sql}" ...

  10. 使用Kernel NetEm和tc模拟复杂网络环境

    关键词:netem(Network Emulator).tc(Traffic Control). 大部分局域网环境良好,但是产品实际网络环境可能千差万别,为了对产品进行各种情况测试就需要模拟网络环境. ...