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,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
随机推荐
- CentOS 6.8 安装JDK8
JDK安装 1.查看环境是否有默认jdk,输入命令: rpm -qa | grep jdk 如果有默认jdk,可以使用 yum remove 删除 2.进入系统根目录,创建developer文件夹 3 ...
- Zabbix远程执行命令
原文发表于cu:2016-06-14 Zabbix触发器(trigger)达到阀值后会有动作(action)执行:发送告警信息或执行远程命令. 本文主要配置验证zabbix执行远程命令. 一.环境 S ...
- 关于购买Redis服务器:腾讯云、阿里云还是华为云?
个人分类: redis使用 编辑 新年伊始,很多商家都开始进行新年产品大促销,在分布是缓存Redis领域,几家大公司也是打得如火如荼,各有千秋啊. 现在市场上比较有口碑的商家有腾讯云.阿里云.华为云三 ...
- Amazon Seller Central is Temporarily Unavailable
Seller Central is Temporarily Unavailable We apologize for the inconvenience. Our technical staff is ...
- 通过Nrgok映射外网调试微信
一.注册账号 注册地址:http://www.ngrok.cc/login 登录系统,新增域名 二.下载客户端,修改配置文件 修改ngrok.cfg auth_token值登录平台管理系统可查看 su ...
- Pythagorean Triples毕达哥斯拉三角(数学思维+构造)
Description Katya studies in a fifth grade. Recently her class studied right triangles and the Pytha ...
- 团队介绍 you i
我们团队一共四个人,我们足够了解对方的优缺点,能够很好的进行交流沟通.对于一些问题也能有好的方法去解决,我做事情比较讲究高效和尽可能的完美,或者说要做到我自己觉得完美,才会停下来.对于一件事情,我有自 ...
- Alpha 冲刺(10/10)
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 测试整体软件 展示GitHub当 ...
- lintcode-206-区间求和 I
206-区间求和 I 给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查询列表.每一个查询列表有两个整数 [start, end] . 对于每个查询,计算出数组中从下标 ...
- 【BioCode】读文件夹以发现缺失文件
代码说明: 使用单个蛋白质的txt计算PSSM生成的结果为单个的PSSM文件. 但是由于一些原因(如蛋白质序列过长),会导致一些蛋白质txt文件无法计算出pssm,为了找到这些没有计算出pssm的蛋白 ...