一个扫地机器人正在清洁一个二维坐标平面。扫地机器人是一个边长 k\times kk×k 的正方形,边与坐标轴平行。初始时,扫地机器人左下角位于 (0,0)(0,0),右上角位于 (k,k)(k,k)。
题目描述
给定一个由 nn 个移动操作组成的序列,第 ii 个移动操作由方向 d_id
i
(N 表示向上,增加 yy 坐标;E 表示向右,增加 xx 坐标;W 表示向左,减小 xx 坐标;S 表示向下,减小 yy 坐标)和距离 a_ia
i
(机器人移动的距离)组成。根据给定的机器人移动操作,计算清扫的总面积(被机器人覆盖过的点就算被清扫过的点)。
输入格式
第一行包含两个整数,机器人的大小 kk 和操作数量 nn。
接下来的 nn 行中,每行包含一个移动操作和对应的距离 a_ia
i
。移动操作用字母 d_id
i
表示(N 即向上,E 即向右,W 即向左,S 即向下),且距离 a_ia
i
是一个整数。
输出格式
输出机器人清扫的总面积。
输入输出样例
输入 #1复制
1 5
E 2
N 2
W 4
S 4
E 4
输出 #1复制
17
输入 #2复制
3 4
W 2
N 1
W 1
N 2
输出 #2复制
27
说明/提示
样例解释:下图是两个样例中机器人的移动情况。
本题使用捆绑测试。
对于 100%100% 数据,1 \le k \le 10^41≤k≤10
4
,1 \le n \le 10^51≤n≤10
5
,1 \le a_i \le 10^91≤a
i
≤10
9
。
注意:机器人可能会走过它之前走过的区域。
#include
#define int long long
using namespace std;
namespace IAOI_lib{
class atlantis{
typedef pair<int,int> pii;
typedef tuple<int,int,int,int> tpi;
private:
struct Line{
int l,r,h,s;
bool operator <(const Line &x)const{
return h<x.h;
}
};
int n;
vector<Line> L;
vector<pii> B;
vector<int> X,C,S;
void build(int u,int l,int r){
if(B[u]=make_pair(l,r);l==r)return;
int m=l+r>>1;
build(u<<1,l,m),build(u<<1|1,m+1,r);
pushup(u);
};
void pushup(int u){
if(C[u])S[u]=X[B[u].second+1]-X[B[u].first];
else S[u]=S[u<<1]+S[u<<1|1];
}
void update(int u,int l,int r,int c){
if(X[B[u].second+1]<=l||r<=X[B[u].first])return;
if(l<=X[B[u].first]&&X[B[u].second+1]<=r)C[u]+=c;
else update(u<<1,l,r,c),update(u<<1|1,l,r,c);
pushup(u);
}
int all_prod(){return S[1];}
public:
int areas_union(vector<tpi> &a){
X.resize(a.size()<<1),L.resize(a.size()<<1);
for(int i=0;i<a.size();i++){
auto &[xa,ya,xb,yb]=a[i];
if(xa>xb)swap(xa,xb); if(ya>yb)swap(ya,yb);
X[i<<1]=xa,X[i<<1|1]=xb;
L[i<<1]=(Line){xa,xb,ya,1},L[i<<1|1]=(Line){xa,xb,yb,-1};
}
sort(L.begin(),L.end(),[](Line x,Line y){return x.h<y.h;});
sort(X.begin(),X.end()),n=unique(X.begin(),X.end())-X.begin();
B.resize(n<<2),C.resize(n<<2),S.resize(n<<3),build(1,0,n-2);
int c=0;
for(int i=0;i+1<a.size()<<1;i++){
update(1,L[i].l,L[i].r,L[i].s);
c+=all_prod()*(L[i+1].h-L[i].h);
}
return c;
}
};
} // 扫描线模板
main(){
ios::sync_with_stdio(false);
int k,n; cin>>k>>n;
vector<tuple<int,int,int,int> > a;
int x=0,y=0; a.emplace_back(0,0,k,k);
while(n--){
char c; int d; cin>>c>>d;
switch(c){
case 'N':a.emplace_back(x,y,x+k,y+d+k),y+=d; break;
case 'E':a.emplace_back(x,y,x+d+k,y+k),x+=d; break;
case 'W':a.emplace_back(x-d,y,x+k,y+k),x-=d; break;
default:a.emplace_back(x,y-d,x+k,y+k),y-=d;
}
} // 依次处理每一条指令
cout<<IAOI_lib::atlantis().areas_union(a)<<endl;
return 0;
}