【ARC101F】Robots and Exits 树状数组优化DP
ARC101F Robots and Exits 树状数组
有 $ n $ 个机器人和 $ m $ 个出口。这 $ n $ 个机器人的初始位置是 $ a_1,a_2.....a_n $ ,这 $ m $ 个出口的位置是 $ b_1,b_2.....b_m $ 。你每次可以让所有机器人往左走一步或往右走一步。当一个机器人所在的位置有一个出口时,这个机器人就会从这个出口出去。问你有多少种让机器人全部离开的方案。两种方案不同当且仅当有至少一个机器人从不同的出口出去。 $ n,m≤100000 $
$ solution: $
首先我们可以将所有在最左端出口以左,最右端出口以右的机器人删掉,他们的最终出口只有一个,不影响答案。
然后我们考虑对于机器人 $ i $ ,它到左边距离它最近的出口的距离为 $ x_i $ ,如果我们往左移的距离超过 $ x_i $ 机器人就会掉进左边这个出口 ;同理设它到右边距离它最近的出口的距离为 $ y_i $ ,如果我们往右移的距离超过 $ y_i $ 机器人就会掉进右边这个出口。为了方便理解,我们先将它放到平面上:
我们考虑这个二维平面的意义:如果我们单纯将机器人左移或右移一个单位,会做很多无用功。但是我们发现,如果我们设 $ (l,r) $ 表示我向左移的最远 $ l $ 步 和向右移的最远 $ r $ 步 ,我们只有将最远步数向外扩展+1,才可能会有机器人掉进出口。而我们如果将这个步数也放到平面上,因为 $ l $ 和 $ r $ 的不断增大,会产生一个折线(如下图一)。我们发现这个折线如果经过某些平行于 $ y $ 轴的直线,它所代表的实际意义就是:对应的机器人会在这条折线与直线相交的时候掉入左边的出口(即当 $ l==x_i $ 时机器人 $ i $ 到达左边出口)
同理,我们发现这个折线如果经过某些平行于 $ x $ 轴的直线,其实际意义为:对应的机器人会在这条折线与直线相交的时候掉入右边的出口(即当 $ r==y_i $ 时机器 $ i $ 到达右边的出口)(如下图二)
我们再仔细观察一下这个平面所能带给我们的信息,我们发现这样一个性质:折线单调递增。折线通过竖直的直线时(继续上图一),这个点一定在折线上方,对应的机器人从左边出口掉落;折线通过水平的直线时(继续上图二),这个点一定在折线下方,对应的机器人从右边出口掉落。这是一个十分有用的性质!因为我们的所求的方案不同,当且仅当有至少一个机器人从不同的出口出去,我们将这个题意转入平面中,意思就是折线上下的点集不同!
然后我们的DP就要登场辣!(好吧,请忽略这个中二病语气)首先我们要设出状态,我们可以根据折线每一次向上走设出状态(只有向上走越过某一条直线才会改变状态),我们设 $ f[i] $ 表示折线最后一次向右转后第一个包括的点为 $ i $ 的所有方案(这个点是所有折线下面的点里最高的点,有多个最高就取最左端的点)。这样设状态不会重复,我们需要仔细思考这样设状态的意义。(这个状态转移是比较难想到的!因为要不重不漏)
然后我们考虑怎么转移:以下图为例,我们的 $ f[i] $ 是包括了点 $ i $ 的,我们如果让折线在包括点 $ i $ 后将状态转移到 $ j $ ,我们必须保证移动过程中 $ j $ 是折线最后一次向右转后第一个包括的点。于是我们可以继续向右移直到这个点 $ j $ 的竖直直线,我们立即向上转,再用折线从 $ j $ 水平直线越过后立即向右转。如下图: $ f[1] $ 可以转移到 $ f[5],f[4],f[3] $ ,所有在它右上方的点都可以!(这样的实际意义就是,我们原本 $ f1 $ 中在点1直接向右转就不往上了,意义是点345都从左边出口出去,现在我们用折线包括后点345分别变成从右边出口出去!)
同理,我们的 $ f2 $ 也可以转移到所有在它右上方的点!
于是我们发现转移方程其实就是这样:每个点的状态可以通过它左下方的点转移过来(我们上面讨论的是转移过去)
$ f[i]=f[j]+1 \quad (x_i>x_j,y_i>y_j) $
这个可以用树状数组维护,我们先将所有点按照纵坐标为第一关键字从低到高排序,横坐标为第二关键字从右到左(从右到左是为了方便转移不重复,注意上面转移方程是两个小于号,我们平面里同一高度左边的点不能转移到右边,它不满足保证移动过程中 $ i $ 是折线最后一次向右转后第一个包括的点,第一个仍旧是原来那一个)。具体实现时,我们直接按顺序枚举所有点的状态,然后按照横坐标将每个点 $ i $ 对应的 $ f[i] $ 存进树状数组,因为我们的枚举的高度从低到高,那么后面我查询时直接在树状数组上查找横坐标-1的前缀和,即可完成转移!
$ code: $
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define db double
#define rg register int
using namespace std;
const int mod=1e9+7;//998244353;
int n,m;
int tt,ans=1; //注意赋了初值1
int a[500005];
int b[500005];
int k[500005]; //离散化
int f[500005]; //计数
int tr[500005]; //树状数组
struct su{
int x,y;
inline bool operator <(const su &z)const{
if(y==z.y)return x>z.x;
return y<z.y;
}
}s[500005];
inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
if(sign)return -res; else return res;
}
inline void add(int x,int v){ //树状数组加入
for(;x<=tt;x+=x&-x) (tr[x]+=v)%=mod;
}
inline int ask(int x){ //树状数组查询
rg res=0;
for(;x;x-=x&-x) (res+=tr[x])%=mod;
return res;
}
int main(){
//freopen("robot.in","r",stdin);
//freopen("robot.out","w",stdout);
n=qr(); m=qr();
for(rg i=1;i<=n;++i) a[i]=qr();
for(rg i=1;i<=m;++i) b[i]=qr(); //已经按顺序排序
for(rg i=1,j=1;i<m&&j<=n;++i){
while(j<=n&&a[j]<=b[i])++j; //找到中间的第一个机器人
if(j>n)break;
while(j<=n&&a[j]<b[i+1]){ //遍历所有在中间的机器人
k[++tt]=a[j]-b[i]; //k数组是用来离散化的
s[tt]=su{k[tt],b[i+1]-a[j]}; ++j; //记录左右距离
}
} sort(k+1,k+tt+1); //离散化
for(rg i=1;i<=tt;++i)
s[i].x=lower_bound(k+1,k+tt+1,s[i].x)-k; //离散化
sort(s+1,s+tt+1); //按纵坐标从小到大,横坐标从大到小
for(rg i=1;i<=tt;++i){
if(s[i].x==s[i-1].x&&s[i].y==s[i-1].y)continue; //去重!
f[i]=(ask(s[i].x-1)+1)%mod; //只有横坐标比它小的才可以转移
ans=(ans+f[i])%mod; //计入答案
add(s[i].x,f[i]); //加入树状数组
}
printf("%d\n",ans);
return 0;
}
【ARC101F】Robots and Exits 树状数组优化DP的更多相关文章
- 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)
[题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...
- HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)
题目链接 2017 CCPC Harbin Problem K 题意 给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_ ...
- Codeforces 946G Almost Increasing Array (树状数组优化DP)
题目链接 Educational Codeforces Round 39 Problem G 题意 给定一个序列,求把他变成Almost Increasing Array需要改变的最小元素个数. ...
- LUOGU P2344 奶牛抗议 (树状数组优化dp)
传送门 解题思路 树状数组优化dp,f[i]表示前i个奶牛的分组的个数,那么很容易得出$f[i]=\sum\limits_{1\leq j\leq i}f[j-1]*(sum[i]\ge sum[j- ...
- 【题解】Music Festival(树状数组优化dp)
[题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)
题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...
- BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)
分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...
随机推荐
- Python 使用 PyQt5 开发的关机小工具
前两天简单认识了一下PyQt5,通过练习开发了一款在Window下自定义关机的小工具,代码如下 import os,sys,time from PyQt5 import QtCore,QtWidget ...
- spring boot官方配置
#BANNER banner.charset = UTF-8 #横幅文件编码.banner.location = classpath:banner.txt #横幅文件位置.banner.image.l ...
- handsonetable+vue 表格在线编辑
<template> <div> <div id="example-container" class="wrapper"> ...
- ubuntu服务器允许Root用户登录
1.重置root密码 sudo passwd root 2.修改ssh配置文件 sudo vim /etc/ssh/sshd_config后进入配置文件中修改PermitRootLogin后的默认值为 ...
- postgresql 10.5 主从复制--搭建测试
env: role master slave host pg1 pg2 ip 11 12 pg-version 10.5 10.5 1 初始化查看 [ceiec@localhost ~]$ df -h ...
- Golang基础(1):Go数据类型和变量
一:Go数据类型 1.1 Go语言按照分类有以下几种数据类型 布尔型 布尔型的是一个常量true或者false 数字类型 整型int和浮点型 float32, float64 字符串类型 字符串就是一 ...
- 【Unity Shader】---数据类型和关键字
一.基本数据类型:Cg支持7种基本的数据类型 1.float,32位浮点数据,一个符号位.浮点数据类型被所有的图形接口支持: 2.half,16位浮点数据: 3.int,32位整形数据 4,fixed ...
- Scratch少儿编程系列:(二)界面介绍及相关概念
本系列后续所有Scratch的讲解均基于2.0版本介绍.系统启动后,界面如下: Scratch主要包括6个区域: 1. 菜单:新建.打开.保存 Scratch文件,2.0版本文件后缀名为 .sb2 2 ...
- 数据结构系列之2-3树的插入、查找、删除和遍历完整版代码实现(dart语言实现)
弄懂了二叉树以后,再来看2-3树.网上.书上看了一堆文章和讲解,大部分是概念,很少有代码实现,尤其是删除操作的代码实现.当然,因为2-3树的特性,插入和删除都是比较复杂的,因此经过思考,独创了删除时分 ...
- Lesson 4 The double life of Alfred Bloggs
There are two type of people in the society. People who do manual works can higher payment than peop ...