1. 程式人生 > >[BZOJ3203][SDOI2013]保護出題人(凸包+三分)

[BZOJ3203][SDOI2013]保護出題人(凸包+三分)

https://www.cnblogs.com/Skyminer/p/6435544.html

先不要急於轉化成幾何模型,先把式子化到底再對應到幾何圖形中去。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 typedef long long ll;
 5 using namespace std;
 6 
 7 const int N=100010;
 8 double ans;
 9 ll d,a[N],x[N],sm[N];
10 int n,top; 11 struct P{ double x,y; }p[N],stk[N]; 12 double sl(P &a,P &b){ return (b.y-a.y)/(b.x-a.x); } 13 14 int main(){ 15 freopen("bzoj3203.in","r",stdin); 16 freopen("bzoj3203.out","w",stdout); 17 scanf("%d%lld",&n,&d); 18 rep(i,1,n){ 19 scanf("%lld%lld
",&a[i],&x[i]); sm[i]=sm[i-1]+a[i]; 20 P t=(P){1.*i*d,1.*sm[i-1]}; 21 while (top>1 && sl(stk[top-1],t)>sl(stk[top],t)) top--; 22 stk[++top]=t; 23 int L=1,R=top; 24 t=(P){1.*x[i]+i*d,1.*sm[i]}; 25 while (L<R-2){ 26 int
m1=L+(R-L)/3,m2=R-(R-L)/3; 27 if (sl(stk[m1],t)<sl(stk[m2],t)) L=m1+1; else R=m2; 28 } 29 double res=0; 30 rep(i,L,R) res=max(res,sl(stk[i],t)); 31 ans+=res; 32 } 33 printf("%.0lf\n",ans); 34 return 0; 35 }