时光倒流+暴力+尺取


第一次看到这题,是在神子杏的课堂上

这就是一个裸的双指针,洛咕上多倍经验的题太多了。 ——神子杏

那好,我们就用双指针来考虑这道题。

首先可以发现

  • 答案区间$ (l,r) $ 一定在某两个标记点之间,也就是说,$l-1 $ 应当是一个有标记点,\(r+1\) 也应是一个有标记的点。

证明很显然,假如右端点的右侧没有标记,那么右端点一定可以继续向右延伸。左端点同理。

往数轴上增加标记不好做,考虑从数轴上拿走标记。我们可以预处理出所有标记点都在数轴上时的答案,也就是输出答案的最后一行。关于这一步,我们可以发现暴力枚举每一个可能的答案区间\((l,r)\)的复杂度为\(O(n^2)\),这显然是不能接受的。发现每当我们确定一个左端点l,则随着l的增大,r是单调不降的。基于这一性质,考虑用双指针扫一遍,\(O(n)\)美滋滋。

接下来考虑依次删去每一个标记,即将这一标记的权值设为\(0\),同时统计对应的答案。统计答案的方法同上。但是我们会发现这样单次复杂度最坏是\(O(n)\),不能接受。

还需要注意的是,题目中要求标记个数不大于k,发现k很小,考虑暴力做。可以发现

  • 删除一个标记点时,至多只会影响这个点左侧k个和右侧k个点(想一想,为什么)。

所以我们只需要在每次删除时,以\(O(k)\)的复杂度用双指针来找这个标记点的左右能不能作为答案即可。

继续考虑优化。删除一个标记,我们不仅删除它的权值,而且删除这个标记的在数组存储中的下标,枚举端点的时候直接跳过它。没错,我们可以使用一个链表来维护每一个端点的前驱和后继。在删除标记时,只需修改其前驱后继的关系即可。

最后需要特判一种情况:删除上一个标记点时的答案区间为\((l0,r0)\),删除当前标记点的答案区间为\((l,r)\),两个区间不是包含关系。这时需要将当前的答案取两者中较大的即可。

则总复杂度为\(O(nk)\)

Code

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e+6+100;
const int inf = 0x7f7f7f7f;
struct Data{
int x,a,tim;
};
int n,m,k;
Data opt[maxn];
int tim[maxn];
int ans[maxn];
int pre[maxn],suc[maxn];
inline int read(){
int v=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-f; ch = getchar();}
while(ch>='0'&&ch<='9'){v=(v<<3)+(v<<1)+ch-'0';ch=getchar();}
return v*f;
}
inline bool cmp(Data x,Data y){
return x.x<y.x;
}
int main(){
n=read();m=read();k=read();
for(register int i=1;i<=n;++i){
opt[i].x=read();opt[i].a=read();opt[i].tim = i;
ans[i] = -1;
}
opt[n+1]=Data{-1,inf,0};
opt[n+2]=Data{m+1,inf,0};
sort(opt+1,opt+n+3,cmp);
for(register int i=1;i<=n+2;++i) tim[opt[i].tim] = i;
for(register int l=1,r=1,cnt=0;r<=n+2;++r){
cnt+=opt[r].a;
while(cnt>k){
cnt-=opt[l++].a;
if(l>r) break;;
}
if(k==0) ans[n] = max(ans[n],opt[r].x-opt[r-1].x-2);
else ans[n]=max(ans[n],opt[r+1].x-opt[l-1].x-2);
}
for(register int i=1;i<=n+2;++i){
if(i!=1)pre[i] = i-1;
suc[i] = i+1;
}
for(register int i=n-1;i>=1;--i){
int t=tim[i+1];
opt[t].a=0;
pre[suc[t]] = pre[t];
suc[pre[t]] = suc[t];
int r=t,lim=t;
for(int p=0;p<=k+10;++p){
r=max(pre[r],2);
lim=min(suc[lim],n+2);
}
for(register int l=r,cnt=0;r<=lim;r=suc[r]){
cnt+=opt[r].a;
while(cnt>k){
cnt-=opt[l].a;
l=suc[l];
}
if(k==0) ans[i] = max(ans[i],opt[r].x-opt[pre[r]].x-2);
else ans[i] = max(ans[i],opt[suc[r]].x-opt[pre[l]].x-2);
}
ans[i]=max(ans[i+1],ans[i]);
}
for(register int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}

洛谷 P6602 数轴的更多相关文章

  1. USACO Section 1.3 题解 (洛谷OJ P1209 P1444 P3650 P2693)

    usaco ch1.4 sort(d , d + c, [](int a, int b) -> bool { return a > b; }); 生成与过滤 generator&& ...

  2. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  3. [洛谷P4609] [FJOI2016]建筑师

    洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...

  4. 【洛谷】P1052 过河【DP+路径压缩】

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙 ...

  5. 「洛谷5017」「NOIP2018」摆渡车【DP,经典好题】

    前言 在考场被这个题搞自闭了,那个时候自己是真的太菜了.qwq 现在水平稍微高了一点,就过来切一下这一道\(DP\)经典好题. 附加一个题目链接:[洛谷] 正文 虽然题目非常的简短,但是解法有很多. ...

  6. 洛谷疯狂coding~

    1.关于数学建模思想在coding之中的应用. 将马路作为一条数轴,每棵树的位置作为数轴上的坐标点,再将坐标点与数组的下标联系到一起,完成建模. 2.本题坑点在于对“其中有多少个数,恰好等于集合中另外 ...

  7. 洛谷P1052 过河

    P1052 过河 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上. 由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青 ...

  8. 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化

    洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...

  9. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

随机推荐

  1. Spring源码解析 | 第一篇 :IntelliJ IDEA2019.3编译Spring5.3.x源码

    前言 工欲善其事必先利其器.学习和深读Spring源码一个重要的前提:编译源码到我们的本地环境.这样方便我们在本地环境添加注释.断点追踪.查看类或接口的继承关系等等,更加高效的学习Spring源码.个 ...

  2. matlab数字图像处理-给图片加入可视水印信息

    将文件夹路径改成了我想要存放代码的文件夹下 然后也是在网上百度,找到了一个代码,敲着模仿了一个 自己建立了一个脚本文件 >>edit test1 然后在脚本中添加 %读取待嵌入水印的图像和 ...

  3. netty之pipeline

    转载自https://blog.csdn.net/zxhoo/article/details/17264263 Netty4学习笔记(1)-- ChannelPipeline Netty4Netty是 ...

  4. ZooKeeper 入门指引

    定义 Apache ZooKeeper is an effort to develop and maintain an open-source server which enables highly ...

  5. 中心极限定理(为什么y服从高斯分布)

    因为每一条数据都服从IID原则: 根据中心极限定理,当数据增加的时候,样本均值的分布慢慢变成正态分布 不管分布式什么分布,累加起来都是高斯分布 As sum increases, sum of non ...

  6. VPS教程:搭建个人网盘教程—kodexplorer

    kodexplorer网盘系统.Kodexplorer,也叫芒果云.可道云.kodcloud,总之名字改了不少.但其本身作为一个网盘文件系统,还是有很多可圈可点的地方. seafile.h5ai.ko ...

  7. 屯点自用CTF网站

    尚且杂乱,刚刚准备搬运东西到博客来,慢慢收拾. 芜湖,起飞  --大司 16进制转换文本 Base64编码转换 quipqiup词频分析 Brainfuck/Ook! Obfuscation/Enco ...

  8. OpenCV计算机视觉学习(2)——图像算术运算 & 掩膜mask操作(数值计算,图像融合,边界填充)

    在OpenCV中我们经常会遇到一个名字:Mask(掩膜).很多函数都使用到它,那么这个Mask到底是什么呢,下面我们从图像基本运算开始,一步一步学习掩膜. 1,图像算术运算 图像的算术运算有很多种,比 ...

  9. JavaScript 将十进制数转换成格式类似于 0x000100 或 #000100 的十六进制数

    将十进制数转换成格式类似于 0x000100 或 #000100 的十六进制数 1 <!DOCTYPE html> 2 <html> 3 <head> 4 < ...

  10. 【题解】[SDOI2017]数字表格

    Link #include<bits/stdc++.h> using namespace std; #define int long long const int MAXN=1e6; in ...