思路是每次离开的时候算出到前面和后面保密室的代价,哪边少就往哪边。
实现就是开一个树状数组记录沿过道的学生人数,然后同一行的就直接暴力算。
不知道是思路还是代码有问题。
//A tree without skin will surely die.
//A man without face is invincible.
#include<bits/stdc++.h>
#define int long long
#define rint register int
using namespace std;
int const N=1e5+10;
int a[N][10],n;
struct Tree_Array{
int c[N<<2];
inline int lowbit(int x){return x&-x;}
inline void update(int x,int v){while (x<=n) c[x]+=v,x+=lowbit(x);}
inline int query(int x){int ans=0;while (x) ans+=c[x],x-=lowbit(x);return ans;}
}T;
signed main(){
ios::sync_with_stdio(false);
cout.tie(0),cout.tie(0);
int m,A,B;cin>>n>>m>>A>>B;
for (rint i=1;i<=n;++i)
for (rint j=1;j<=6;++j)
a[i][j]=1;
for (rint i=1;i<=n;++i) T.update(i,2);
int front=0,behind=0,ans=0;
for (rint i=1;i<=m;++i){
string s;cin>>s;
int h=s[0]-'0',c=s[1]-'A'+1,sumc=0;
if (c<=3){
for (rint j=c+1;j<=4;++j)
sumc+=a[h][j];
}else{
for (rint j=3;j<=c-1;++j)
sumc+=a[h][j];
}
if ((sumc+T.query(h-1))*A+front*B<=(sumc+T.query(n)-T.query(h))*A+behind*B){
ans+=(sumc+T.query(h-1))*A+front*B;++front;
}else{
ans+=(sumc+T.query(n)-T.query(h))*A+behind*B;++behind;
}
if ((c==3 || c==4)&& a[h][c]) T.update(h,-1);
a[h][c]=0;
}
cout<<ans<<'\n';
return 0;
}