P7701
题面
有
题解
你好。
可以发现按顺序这一点很重要,由此推出对于每个人,它往前往后走所经过的人数总是不变。
所以可以预处理第
然后,若上面的房间有
于是就可以这样想:若
从贪心的角度,可以发现选取能省代价最多的
接着,枚举
对于
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+2;
ll n,m;
char s[10];
ll A,B,ans;
ll tr[N];
bool mp[N][8];
struct node{
ll a,b;
} p[6*N];
int lowbit(int x) {return x&(-x);}
void add(int x,int val) {
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=val;
return;
}
ll sum(int x) {
int sum=0;
for(int i=x;i;i-=lowbit(i)) sum+=tr[i];
return sum;
}
bool cmp(node a,node b) {
return (a.a-a.b)>(b.a-b.b);
}
int main() {
scanf("%lld%lld%lld%lld",&n,&m,&A,&B);
for(int i=1;i<=n;i++) {add(i,2);for(int j=1;j<=6;j++) mp[i][j]=true;}
for(int i=1;i<=m;i++) {
cin>>s;
int x=0,y=s[strlen(s)-1]-'A'+1;
for(int i=0;i<strlen(s)-1;i++) x=x*10+s[i]-'0';
if(y==1) p[i].a+=mp[x][2],p[i].b+=mp[x][2];
if(y==6) p[i].a+=mp[x][5],p[i].b+=mp[x][5];
if(y==3||y==4) add(x,-1);
mp[x][y]=false;
p[i].a+=sum(x),p[i].b+=sum(n)-sum(x-1);
}
sort(p+1,p+1+m,cmp);
for(int i=1;i<=m;i++) p[i].a+=p[i-1].a,p[i].b+=p[i-1].b;
ans=1e16;
for(ll i=0;i<=m;i++) ans=min(ans,A*(p[i].b+p[m].a-p[i].a)+B*(i*(i-1ll)/2ll+(m-i-1ll)*(m-i)/2ll));
printf("%lld",ans);
return 0;
}