题解 P4266 【[USACO18FEB]Rest Stops】
此题可以优化到O(N)
在
既然我们不必在乎其他不是最优解的价值,排序没有必要。
只须先逆序扫一遍所有的休息站,找出在每一阶段的最优解,将其记录在一个数组中,在第二遍扫的时候,算出价值即可。
49ms,luogu 1st。
#include <cstdio>
#include <iostream>
#include <cctype>
#include <cstring>
#include <map>
#include <stack>
#include <utility>
#include <string>
#include <algorithm>
#define gc() getchar()
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dec(i,a,b) for(int i=(a);i>=(b);--i)
#define endll putchar('\n');
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int MAXOUT=10000;
const int MAXBUF=10000;
char buf[MAXBUF],*ps=buf,*pe=buf+1;
inline void rnext(){
if(++ps == pe)
pe = (ps = buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin);
}
inline bool in(ll &ans){
ans = 0;
ll f = 1;
if(ps == pe) return false;//EOF
do{
rnext();
if('-' == *ps) f = -1;
}while(!isdigit(*ps) && ps != pe);
if(ps == pe) return false;//EOF
do{
ans = (ans<<1)+(ans<<3)+*ps-48;
rnext();
}while(isdigit(*ps) && ps != pe);
ans *= f;
return true;
}
char bufout[MAXOUT], outtmp[50],*pout = bufout, *pend = bufout+MAXOUT;
inline void write(){
fwrite(bufout,sizeof(char),pout-bufout,stdout);
pout = bufout;
}
inline void out_char(char c){ *(pout++) = c;if(pout == pend) write();}
inline void out_str(char *s){
while(*s){
*(pout++) = *(s++);
if(pout == pend) write();
}
}
inline void out_int(ll x) {
if(!x){
out_char('0');
return;
}
if(x < 0) x = -x,out_char('-');
int len = 0;
while(x){
outtmp[len++] = x%10+48;
x /= 10;
}
outtmp[len] = 0;
for(int i = 0, j = len-1; i < j; i++,j--) swap(outtmp[i],outtmp[j]);
out_str(outtmp);
}
inline void out_int_ln(ll k){
out_int(k);
out_char('\n');
}
const int maxn=101101;
ll l,n,rf,rb;
struct kusa{
ll dis,val;
kusa(){}
kusa(ll _dis,ll _val){dis=_dis;val=_val;}
}k[maxn];
bool operator <(const kusa &a,const kusa &b){
if(a.val==b.val) return a.dis>b.dis;
return a.val>b.val;
}
ll ans;
ll tmp_max;
bool decmax[maxn];
int tmp_dis=0;
int main(){
in(l),in(n),in(rf),in(rb);
rep(i,1,n) in(k[i].dis),in(k[i].val);
dec(i,n,1)
if(k[i].val>tmp_max) decmax[i]=true,tmp_max=k[i].val;
rep(i,1,n)
if(decmax[i]==true){
ans+=k[i].val*(rf-rb)*(k[i].dis-tmp_dis);
tmp_dis=k[i].dis;
}
out_int_ln(ans);
write();
return 0;
}