记录编号 142710 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2011]设计铁路 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.166 s
提交时间 2014-12-10 15:05:29 内存使用 3.15 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int SIZEN=40010;
class Point{
public:
	LL x,y;
};
Point operator - (Point a,Point b){return (Point){a.x-b.x,a.y-b.y};}
LL cross(Point a,Point b){//a逆时针到b的有向三角形面积
	return a.x*b.y-b.x*a.y;
}
class Hull{//下凸壳
public:
	Point s[SIZEN];
	int n,head,tail;//0~n-1
	void clear(void){n=0;head=tail=0;}
	Hull(void){clear();}
	void insert(Point p){
		while(n>=2&&cross(s[tail-1]-p,s[tail-2]-p)>=0) n--,tail--;
		s[tail++]=p;n++;
	}
	LL calc(Point a,LL k){
		return a.x*k+a.y;
	}
	LL calc(LL k){
		while(n>=2&&calc(s[head],k)>=calc(s[head+1],k)) n--,head++;
		return calc(s[head],k);
	}
}H;
LL N,M;
pair<LL,LL> V[SIZEN];//村庄们
LL RS[SIZEN]={0},MS[SIZEN]={0};//RS是R的前缀和,MS是R*T的前缀和
LL f[SIZEN]={0};
Point turn_point(int k){
	return (Point){V[k].first,f[k]-MS[k]+V[k].first*RS[k]};
}
void work(void){
	H.clear();
	H.insert(turn_point(0));
	for(int i=1;i<=N;i++){
		f[i]=H.calc(-RS[i-1])+M+MS[i-1];
		H.insert(turn_point(i));
	}
	printf("%lld\n",H.calc(-RS[N])+MS[N]);//即f[N+1]-M
}
void init(void){
	scanf("%lld%lld",&N,&M);
	for(int i=1;i<=N;i++) scanf("%lld%lld",&V[i].first,&V[i].second);
	sort(V+1,V+1+N);
	for(int i=1;i<=N;i++){
		RS[i]=RS[i-1]+V[i].second;
		MS[i]=MS[i-1]+(V[i].first*V[i].second);
	}
}
int main(){
	freopen("nt2011_design.in","r",stdin);
	freopen("nt2011_design.out","w",stdout);
	init();
	work();
	return 0;
}