CF765F Souvenirs 解题报告
CF765F Souvenirs
题意翻译
给出\(n(2 \le n \le 10^5 )\) ,一个长为\(n\)的序列\(a(0 \le a_i \le 10^9 )\)。
给出\(m(1\le m \le 2*10^5 )\),接下来\(m\)组询问。
每组询问给出一个\(l,r(1\le l < r\le n )\),代表询问最小的\(|a_i-a_j|\) 的值(\(l\le i <j\le r\) ,\(a_i\) 可以等于\(a_j\) )
蒟蒻\(\tt{Dew}\)又双叒叕花大几个小时去弄懂这个题,而直到现在,我也只是明白了这个题为什么可以这么做,却不是太明白这种题如何去想。
首先可以看出这个题说不定可以莫队套平衡树卡过去,没什么别的想法还是写写吧,估计比暴力还是强一些的。
然后考虑一些思考的出发点,比如
- 值域?二分值域?划分修改?
- 移动询问的指针?
- 把询问给线段树分治掉?
- 单调性?
不妨先考虑一些简单的暴力,比如说,我们把询问按右指针排序,然后开始处理它们。
若当前处理到的位置为\(r\),我们对\(r\)前面的位置\(i\)维护答案数组\(ans_i\),代表区间\([i,r]\)的答案,每次移动右指针时,我们暴力更新每个位置的答案。
考虑修补这个暴力。
- 发现询问\(ans_i\)也可以看做询问\(\min_{i\le k <r} ans_k\),这启发我们去区间查询,然后每次移动时不修改所有的值,选择线段树进行维护。
- 具体的,在线段树上点代表的区间上,存下这个区间所有的\(a_i\),然后在这个区间上二分就能够更新这个区间的答案了。
- 然后发现复杂度更高了,按道理有些值是不需要修改的,哪些值呢?
- 发现\(ans_i\)数组是单调不升的。如果我们成功修改了位置靠右的某个值,并设当前的答案为\(mi\)(注意这个是包含原本节点的答案的最小值),那么在一个某个在\(Ta\)左边的节点上贡献的答案不如\(mi\)时,我们就没有必要进入这个节点的子节点了。
- 这样做的复杂度单次操作是\(\log n \log Maxa_i\)的,原因其实很简单,每次成功贡献答案后答案必定减半。为什么?如果\(r\)对\(j\)的答案为\(mi_j\),\(r\)对\(i\)的答案为\(mi_i\),为了避免\(i\)直接把\(j\)给更新掉,一定有\(mi_i< \frac{mi_j}{2}\)
总结:积累做题经验,多开脑洞..
Code:
#include <cstdio>
#include <algorithm>
#include <vector>
const int N=1e5+10;
struct node
{
int i,l,r;
bool friend operator <(node n1,node n2){return n1.r<n2.r;}
}q[N<<2];
int ans[N<<2],Ans[N<<2],n,m,a[N],mi;
std::vector <int> seg[N<<2];
int min(int x,int y){return x<y?x:y;}
#define ls id<<1
#define rs id<<1|1
const int inf=0x3f3f3f3f;
void build(int id,int l,int r)
{
for(int i=l;i<=r;i++) seg[id].push_back(a[i]);
std::sort(seg[id].begin(),seg[id].end());
ans[id]=inf;
if(l==r) return;
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
}
void change(int id,int l,int r,int p,int x)
{
if(r<=p)
{
std::vector <int>::iterator it=std::upper_bound(seg[id].begin(),seg[id].end(),x);
if(it!=seg[id].end()) ans[id]=min(ans[id],*it-x);
if(it!=seg[id].begin()) ans[id]=min(ans[id],x-*(it-1));
if(mi<=ans[id]) return;//右边已经有比Ta优秀的了
if(l==r){mi=min(mi,ans[id]);return;}
}
int mid=l+r>>1;
if(p>mid) change(rs,mid+1,r,p,x);//注意先走右边
change(ls,l,mid,p,x);
ans[id]=min(ans[id],min(ans[ls],ans[rs]));
mi=min(mi,ans[id]);//最后更新Ta
}
int query(int id,int L,int R,int l,int r)
{
if(L==l&&R==r) return ans[id];
int Mid=L+R>>1;
if(r<=Mid) return query(ls,L,Mid,l,r);
else if(l>Mid) return query(rs,Mid+1,R,l,r);
else return min(query(ls,L,Mid,l,Mid),query(rs,Mid+1,R,Mid+1,r));
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].i=i;
}
std::sort(q+1,q+1+m);
for(int p=1,i=2;i<=n;i++)
{
mi=inf;
change(1,1,n,i-1,a[i]);
for(;p<=m&&q[p].r<=i;++p)
Ans[q[p].i]=query(1,1,n,q[p].l,i);
}
for(int i=1;i<=m;i++)
printf("%d\n",Ans[i]);
return 0;
}
2018.11.29
CF765F Souvenirs 解题报告的更多相关文章
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
随机推荐
- javaweb(三十七)——获得MySQL数据库自动生成的主键
测试脚本如下: 1 create table test1 2 ( 3 id int primary key auto_increment, 4 name varchar(20) 5 ); 测试代码: ...
- XAF-属性编辑器中的EditMask,DisplayFormat格式化字符串该如何设置
XAF项目中有个DisplayFormat和EditMask设置,其中: 任何地方看到的DisplayFormat都是用于显示时,即非修改状态的编辑器,显示值的格式. EditMask是指编辑时的格式 ...
- 深圳第XX天
今天早晨,面了一家小公司.先说结果吧,面过了.但是,总感觉太假了.面试中很多问题都没有回答上来.然后老板看了一下简历,问:期薪资多少?我想了想,说7000.啊,要不留下来看看?我答应了.不到十分钟,就 ...
- 3星|《CMO到底能干多久?》:CEO必须决定供公司需要哪类CMO
CMO到底能干多久?(<哈佛商业评论>增刊) <哈佛商业评论>关于CMO的6篇文章.我认为第一篇<为何CMO宝座坐不长>写的最好,是典型的哈评风格:做过实际调查.有 ...
- Pairs Forming LCM LightOJ - 1236 素因子分解
Find the result of the following code: long long pairsFormLCM( int n ) { long long res = 0; fo ...
- Open vSwitch for CentOS
原文发表于cu:2016-06-02 本文属于重发,ovs当前的安装方式可能略有不同. 参考文档: 官方文档: http://openvswitch.org/support/dist-docs-2.5 ...
- 技本功丨利用 Atomic 构建 React 项目工作流,so easy!
近日刷微博,#2018年结婚率创新低#荣登热门话题NO.1,沪浙最不积极. 生活压力越大,缺爱的人也越来越多...据本萌的不完全观察,程序猿虽然是压力加成的职业,在袋鼠云还是有不少早早脱了单.至于,脱 ...
- ZOJ 3962
就是统计1~n中出现的各个数字的次数,当然是在16进制下. 不过有个区间问题的小技巧,统计从 [x,y] 可以转换成 从 [1,y] 减去 [1,x-1]. 不过要分类讨论一下,因为有可能会出现溢出, ...
- Visionpro学习网
重码网是一个在线机器视觉学习网站,推出了Halcon,Visionpro机器视觉学习视频教程,视频内容通俗易懂,没有编程基础的同学,照着视频练习,也同样可以学会. 学机器视觉,拿高薪,成就技术大拿.重 ...
- 在GPT格式的硬盘上,使用EFI启动的方式,安装Win7 64位系统
Win7 sp1 原装系统,用UltraISO(软碟通) 把U 盘制成Win7 安装的启动U盘 将bootmgfw.efi和shell.efi 加到已制好启动U盘的根目录,并在efi/boot/路径下 ...