【arc073f】Many Moves(动态规划,线段树)

题面

atcoder

洛谷

题解

设\(f[i][j]\)表示第一个棋子在\(i\),第二个棋子在\(j\)的最小移动代价。

发现在一次移动结束之后,总是有一个棋子会动到当前位置,因此状态改为当前是第\(i\)次操作,第\(i\)次操作没有动的那个棋子在\(j\)位置时的最小代价。

把第一维省掉,用线段树动态维护这个数组。

每次枚举移动哪一个棋子,直接线段树对应修改即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MAX 200200
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q,A,B,a[MAX];ll f[MAX];
struct SegMentTree
{
ll t[MAX<<2],tag[MAX<<2],a[MAX];
void pushup(int now){t[now]=min(t[lson],t[rson]);}
void Build(int now,int l,int r)
{
if(l==r){t[now]=f[l]+a[l];return;}
int mid=(l+r)>>1;tag[now]=0;
Build(lson,l,mid);Build(rson,mid+1,r);
pushup(now);
}
void puttag(int now,ll w){t[now]+=w;tag[now]+=w;}
void pushdown(int now)
{
if(!tag[now])return;
puttag(lson,tag[now]);
puttag(rson,tag[now]);
tag[now]=0;
}
void Modify(int now,int l,int r,int p,ll w)
{
if(l==r){t[now]=min(t[now],w);return;}
int mid=(l+r)>>1;pushdown(now);
if(p<=mid)Modify(lson,l,mid,p,w);
else Modify(rson,mid+1,r,p,w);
pushup(now);
}
void Modify(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){puttag(now,w);return;}
int mid=(l+r)>>1;pushdown(now);
if(L<=mid)Modify(lson,l,mid,L,R,w);
if(R>mid)Modify(rson,mid+1,r,L,R,w);
pushup(now);
}
ll Query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[now];
int mid=(l+r)>>1;ll ret=4e18;pushdown(now);
if(L<=mid)ret=min(ret,Query(lson,l,mid,L,R));
if(R>mid)ret=min(ret,Query(rson,mid+1,r,L,R));
return ret;
}
}T1,T2;
ll Solve(int A,int B)
{
memset(f,63,sizeof(f));f[B]=abs(A-a[1]);
for(int i=1;i<=n;++i)T1.a[i]=-i,T2.a[i]=i;
T1.Build(1,1,n);T2.Build(1,1,n);
ll inf=f[0];f[B]=inf;f[1]=abs(A-a[1]);
for(int i=2;i<=Q;++i)
{
ll ret=inf;
ret=min(ret,T1.Query(1,1,n,1,a[i])+a[i]);
ret=min(ret,T2.Query(1,1,n,a[i],n)-a[i]);
T1.Modify(1,1,n,1,n,abs(a[i]-a[i-1]));
T2.Modify(1,1,n,1,n,abs(a[i]-a[i-1]));
T1.Modify(1,1,n,a[i-1],ret-a[i-1]);
T2.Modify(1,1,n,a[i-1],ret+a[i-1]);
ret=min(ret,f[i-1]+abs(a[i]-a[i-1]));
f[i]=ret;
}
return f[Q];
}
int main()
{
n=read();Q=read();A=read();B=read();
for(int i=1;i<=Q;++i)a[i]=read();
printf("%lld\n",min(Solve(A,B),Solve(B,A)));
return 0;
}

【arc073f】Many Moves(动态规划,线段树)的更多相关文章

  1. BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树

    BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树 题意:  约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群 ...

  2. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  3. Codeforces 834D The Bakery - 动态规划 - 线段树

    Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...

  4. Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆

    背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...

  5. 【BZOJ3939】[Usaco2015 Feb]Cow Hopscotch 动态规划+线段树

    [BZOJ3939][Usaco2015 Feb]Cow Hopscotch Description Just like humans enjoy playing the game of Hopsco ...

  6. BZOJ4881 线段游戏(二分图+树状数组/动态规划+线段树)

    相当于将线段划分成两个集合使集合内线段不相交,并且可以发现线段相交等价于逆序对.也即要将原序列划分成两个单增序列.由dilworth定理,如果存在长度>=3的单减子序列,无解,可以先判掉. 这个 ...

  7. 【BZOJ2090/2089】[Poi2010]Monotonicity 2 动态规划+线段树

    [BZOJ2090/2089][Poi2010]Monotonicity Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度 ...

  8. arc073 F many moves(dp + 线段树)

    设dp[i][y]表示一个点在x[i],另一个点在y时最小要走的步数 那么有以下转移 对于y != x[i-1]的状态,可以证明,他们直接加|x[i] - x[i-1]|即可(如果有其他方案,不符合对 ...

  9. BZOJ 4881: [Lydsy1705月赛]线段游戏 动态规划 + 线段树

    Description quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐 标分别为(0,i)和(1,p_i),其中p_1,p_2,. ...

  10. bzoj 1835 base 基站选址 - 动态规划 - 线段树

    题目传送门 需要高级权限的传送门 题目大意 有$n$个村庄坐落在一条直线上,第$i \ \ \ (i>1)$个村庄距离第$1$个村庄的距离为$D_i$.需要在这些村庄中建立不超过$K$个通讯基站 ...

随机推荐

  1. 替换iframe的内容

    一般就是点个按钮然后在不跳转页面的情况下显示另外一个页面的内容,显示的速度比较快,ifream还算是常用的吧 用的时候实现方式有以下几种, 1.替换src路径(觉得麻烦,没接触过,就不这样干了) 2. ...

  2. C#设计模式之1:策略模式

    首先需要说明的是该系列的所有内容都是基于headfirst设计模式来描述的.因为我之前也看过不少关于设计模式的书,还是发现这本最好,因为这本书里面给出的例子是最贴切实际的.不说了,开始这个系列吧! 策 ...

  3. ArrayList的扩容机制

    一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...

  4. 《笔记》Python itertools的groupby分组数据处理

    今天遇到这么一个需求,需要将这样的数据进行分组处理: [(, ), (, ), (, ), (, ), (, ), (, )] 处理之后我可能需要得到这样的结果: [(, (, , (, , (, ) ...

  5. 离线安装redis-cluster

    #离线安装redis-cluster https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.tar.gz #安装ruby .tar.gz cd rub ...

  6. mysql数据库的备份和还原的总结

    mysql数据库的备份和还原的总结 (来自一运维同事的总结) 1. 备份方式: 热备:数据库在线进行备份,不影响读和写的在线备份方式! 温备:数据库在线进行备份,对表备份时先锁定写操作,仅可以执行读操 ...

  7. comparable和comparator

    Comparable Comparable可以认为是一个内部比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,在compareTo方法中指定具体的比较方法. comp ...

  8. 老男孩python学习自修第十六天【常用模块之sys和os】

    例子: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys. ...

  9. solr配置ik中文分词(二)

    上一篇文章主要介绍了solr的安装与配置,这篇文章主要记录如何使用ik分词器对中文进行分词. 步骤: 1.下载ik分词jar包:ik-analyzer-solr5-5.x.jar. 2.将下载的jar ...

  10. How to SHA1 on macOS

    openssl sha1 /volumes/test/install/osx-test.dmg