将机器人 i 距离其左出口和右出口的距离记成x_i , y_i ,如果有两头端点的一些机器人只有左出口或者只有有出口,就不记录x_i 和 y_i 了,因为他们只有一个出口供选择,不会影响最终出口选择方案的数量
记机器人们(相对自身原来位置)向左走的最大距离为x,向右走的最大距离为y,则不管具体行走路线是什么样的,要么x增加1,要么y增加1,这两种情况才有可能造成机器人走向出口的实质性改变
好的,以上实际上是铺垫,关键的步骤是将x_i y_i和x,y放入平面直角坐标系中,接下来的内容用手写的方式展现
分隔线
编辑
然后还有一些实现的细节技巧,两个机器人的x_i=x_j,y_i=y_j,这种情况只算一个机器人,因为坐标范围很大,可以将点按照先x小后y大的方式排序,这样使用动态规划数组dp[h],h代表点的y坐标,每次更新dp[h]=dp[h1]的和(h1<h)+1就可以保证x_j<x_i并且y_y<y_i,然后因为h坐标也很大,所以将h离散化后实现求前缀和,以下的程序用线段树实现,用树状数组也可以
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=1e5+5,mod=1e9+7;
int n,m,botcnt,ycnt;
int a[maxn],b[maxn],y[maxn];
ll tree[maxn<<2];
struct Robot{
int x,y;
bool operator < (const Robot &rhs) const {
if(x==rhs.x) return y>rhs.y;
return x<rhs.x;
}
bool operator == (const Robot &rhs) const {
return x==rhs.x && y==rhs.y;
}
}bot[maxn];
inline int ls(int x) {return x<<1;}
inline int rs(int x) {return (x<<1)|1;}
void push_up(int p){
tree[p]=tree[ls(p)]+tree[rs(p)];
}
void update(int p,int pl,int pr,int L,int R,ll d){
if(pl>=L && pr<=R){
tree[p]=(tree[p]+d)%mod;
return;
}
int mid=(pl+pr)>>1;
if(L<=mid) update(ls(p),pl,mid,L,R,d);
if(R>mid) update(rs(p),mid+1,pr,L,R,d);
push_up(p);
}
ll query(int p,int pl,int pr,int L,int R){
if(pl>=L && pr<=R){
return tree[p];
}
ll res=0;
int mid=(pl+pr)>>1;
if(L<=mid) res=(res+query(ls(p),pl,mid,L,R))%mod;
if(R>mid) res=(res+query(rs(p),mid+1,pr,L,R))%mod;
return res;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
stable_sort(b+1,b+1+m);
for(int i=1;i<=n;i++){
if(a[i]<b[1] || a[i]>b[m]) continue;
int k=lower_bound(b+1,b+1+m,a[i])-b-1;
bot[++botcnt].x=a[i]-b[k];
bot[botcnt].y=b[k+1]-a[i];
y[++ycnt]=bot[botcnt].y;
}
stable_sort(bot+1,bot+1+botcnt);
botcnt=unique(bot+1,bot+1+botcnt)-bot-1;
stable_sort(y+1,y+1+ycnt);
ycnt=unique(y+1,y+1+ycnt)-y-1;
for(int i=1;i<=botcnt;i++){
int k=lower_bound(y+1,y+1+ycnt,bot[i].y)-y;
if(k>1)
update(1,1,ycnt,k,k,(query(1,1,ycnt,1,k-1)+1)%mod);
else
update(1,1,ycnt,k,k,1);
}
cout<<(query(1,1,ycnt,1,ycnt)+1)%mod<<"\n";
return 0;
}