前言

\(ZHK\)私人博客体验更佳

这道题目,\(n<=10^5\),显然在暗示我们使用\(n \log n\)的做法,我就是用了一个简单的贪心,通过了此题。

正文

在这道题中,我们发现,可以把 \(Bessie\) 每次走的路看成是对序列的一段区间染色。

for(int i=1;i<=n;i++){
int x;char y;
read(x);cin>>y;
a[i].l=position;
if(y=='L')position-=x;//Bessie往左走
else position+=x;//Bessie往右走
a[i].r=position;
if(a[i].l>a[i].r)swap(a[i].l,a[i].r);
}

这里的 \(a\)数组是一个结构体——\(node\)

const int MAXN=1e5+10;
struct node{
int l,r;//每次染色的左端点和右端点
bool operator<(const node&b)const{
return l<b.l;//按左端点从小到大排序
}
}a[MAXN];

之后,我们就要说真正的思路了,我们对于 \(a\) 序列排序后,会有这样一个画面。

我们定义两个变量——\(lft\)和\(rgt\),记录可能区间的左端点和右端点。

这里面我们记录的是有可能和下面相交的区间,什么意思?比如那张图,我们标一下号

当我么扫描第 \(1\) 个区间时,我们发现,之后有可能被覆盖到的区间是 \(lft=0,rgt=15\)。

当我们继续扫描,到第 \(2\) 个区间时,我们发现,之后可能被覆盖到的区间是 \(lft=15,rgt=18\)。

可能有人会问,\(5\)~\(15\) 这段消失,我们还能理解,但是为什么 \(0\)~\(5\) 这段也没了呢,因为第 \(2\) 个区间的\(l\)都大约 \(0\) 了,之后的区间肯定就更大于 \(0\) 了,我们是按 \(l\) 从小到大排序的啊。

所以,我可以放一下代码了:

for(int i=2;i<=n;i++)
if(a[i].r>lft){//如果跟可能被覆盖到的区间有交
a[i].l=max(a[i].l,lft);//这里是使得之后的代码可以少写一点,因为显然,a[i].l<lft,a[i].l~lft这1段也没有用了
if(a[i].r>rgt){//比之前的右端点大
ans+=rgt-a[i].l;//从rgt到a[i].l
lft=rgt;//之前的右端点显然就是左端点,显然,新的可能被覆盖到的区间就是之前的rgt~a[i].r
rgt=a[i].r;//更新右端点
}else{//比之前的右端点小
ans+=a[i].r-a[i].l;//从a[i].r到a[i].l
lft=a[i].r;//更新左端点
}
}

总结

我们先来看一下完整的代码:

#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}//快读
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}//快写
const int MAXN=1e5+10;
struct node{
int l,r;//每次染色的左端点和右端点
bool operator<(const node&b)const{
return l<b.l;//按左端点从小到大排序
}
}a[MAXN];
int position,ans,lft,rgt,n;
int main(){
read(n);
for(int i=1;i<=n;i++){
int x;char y;
read(x);cin>>y;
a[i].l=position;
if(y=='L')position-=x;//Bessie往左走
else position+=x;//Bessie往右走
a[i].r=position;
if(a[i].l>a[i].r)swap(a[i].l,a[i].r);
}sort(a+1,a+n+1);//排序
lft=a[1].l;rgt=a[1].r;//给lft和rgt赋上初值
for(int i=2;i<=n;i++)
if(a[i].r>lft){//如果跟可能被覆盖到的区间有交
a[i].l=max(a[i].l,lft);//这里是使得之后的代码可以少写一点,因为显然,a[i].l<lft,a[i].l~lft这1段也没有用了
if(a[i].r>rgt){//比之前的右端点大
ans+=rgt-a[i].l;//从rgt到a[i].l
lft=rgt;//之前的右端点显然就是左端点,显然,新的可能被覆盖到的区间就是之前的rgt~a[i].r
rgt=a[i].r;//更新右端点
}else{//比之前的右端点小
ans+=a[i].r-a[i].l;//从a[i].r到a[i].l
lft=a[i].r;//更新左端点
}
}
write(ans);//输出
return 0;
}

补充一下正确性证明:

实际上作者想到这个方法的时候觉得显然是对的

其实主要就是为什么要 \(lft=a[i].r\) 可能有人对此有点问题,我来解释一下

\(\therefore\) 我们是按从小到大对 \(a\) 数组进行排序,也就是 \(a[i+1].l \geq a[i].l\),而 \(a[i].l>lft\)

\(\because\) \(a[i+1].l>lft\)。

最新文章

  1. Linux系统GCC常用命令和GCC编译过程描述
  2. JavaDate类
  3. 将数据文件从普通文件系统移动到ASM
  4. spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable
  5. Runner之记计账项目的典型用户分析
  6. codeforces C. Prime Swaps
  7. C#如何以管理员身份运行程序(转)
  8. Laravel-高级篇-Artisan
  9. shuffle一个简单的过程叙述性说明
  10. css 小知识
  11. 不可变对象和Biulder模式(面试问题)
  12. Dynamics 365 CRM Free up storage 清理Dynamics 365 CRM的空间
  13. Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
  14. Expm 9_2 有向图的强连通分量问题
  15. [BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]
  16. BZOJ 4004: [JLOI2015]装备购买
  17. R语言学习——条件筛选
  18. Eclipse变量名自动补全问题 自定义上屏按键为TAB
  19. vmvare11克隆centos虚拟机
  20. ubuntu 上查看文件的内容,二进制形式展现

热门文章

  1. [PyTorch入门]之从示例中学习PyTorch
  2. Docker 安装 Nginx 负载均衡配置
  3. linux入门系列17--邮件系统之Postfix和Dovecot
  4. 1,Java知识储备
  5. 什么是Activiti
  6. 30分钟学会Objective-C
  7. 差分放大电路的CMRR与输入电阻分析
  8. 前端每日实战:74# 视频演示如何用纯 CSS 创作一台 MacBook Pro
  9. PySide2的This application failed to start because no Qt platform plugin could be initialized解决方式
  10. python3编写程序,根据输入的行列数值,生成相应的矩阵(其中元素为随机数)。