这就是我在游记里讲的那个 (O(45n log n)) 的垃圾写法。不知道为什么我对这题最直观的写法就是这个。
思路就是如果是地铁,就放到一个数组中(代码中用结构体实现),如果是公交车,就放到 map 里(那个 (log) 就是这么来的)。
然后再写一个二重循环,反正枚举就是了。
最后把 map 扫一遍。
我考场上怂,在正解的基础上写了 (price_i) 都相等的部分分。
下面是考场代码,写的很乱:
#include <bits/stdc++.h>
using namespace std;
const int maxN=100005;
int n;
struct Node {
int price;
int t;
}a[maxN];
priority_queue<int,vector<int>,greater<int> > q;
map<int,int> mp;
map<int,int> PRICE;
int ans,tot;
void rd(int&);
int OP[maxN],X[maxN],Y[maxN];
bool check();
void spwork();
int main() {
freopen("transfer.in","r",stdin);
freopen("transfer.out","w",stdout);
rd(n);
//if (n<=1000)
// task1::work();
for (register int i=1;i<=n;i++) {
//int op,x,y;
rd(OP[i]),rd(X[i]),rd(Y[i]);}if (check()){spwork();return 0;}
for (register int i=1;i<=n;i++) {
if (!OP[i]) {
a[++tot].price=X[i];
a[tot].t=Y[i];
ans+=X[i];
}
if (OP[i]==1) {
mp[Y[i]]=1;
PRICE[Y[i]]=X[i];
}
}
//cout<<"tot="<<tot<<'
';
for (register int i=1;i<=tot;i++)
for (register int j=1;j<=45;j++) {
if (!mp[a[i].t+j]||PRICE[a[i].t+j]>a[i].price)
continue;
mp[a[i].t+j]=0;
//cout<<"a[i].t+j="<<a[i].t+j<<'
';
break;
}
map<int,int> :: iterator it;
for (it=mp.begin();it!=mp.end();it++) {
if (it->second)
ans+=PRICE[it->first];
//cout<<"it->second="<<it->second<<'
';
}
//for (map<int,int> :: iterator it=PRICE.begin();it!=PRICE.end();it++)
//cout<<"it->first="<<it->first<<" it->second="<<it->second<<'
'; PRICE ok
//for (map<int,int> :: iterator it=mp.begin();it!=mp.end();it++)
// cout<<"it->first="<<it->first<<" it->second="<<it->second<<'
';
cout<<ans<<'
';
//cout<<clock();
return 0;
}
void rd(int& x) {
x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch)) {
x=x*10+ch-48;
ch=getchar();
}
}
bool check() {
for (int i=2;i<=n;i++)
if (X[i]!=X[i-1])
return false;
return true;
}
void spwork() {
int ans=0;
for (int i=1;i<=n;i++) {
if (!OP[i])
q.push(Y[i]),ans+=X[i];
if (OP[i]==1) {
bool flag=true;
while (!q.empty()) {
if (Y[i]-q.top()>45)
q.pop();
else {
q.pop();
flag=false;
break;
}
}
if (flag) {
ans+=X[i];
}
}
}
cout<<ans<<'
';
}