bzoj3203: [Sdoi2013]保護出題人
阿新 • • 發佈:2018-04-22
AI name tdi struct class d+ namespace 2.x OS
我三分這麽好嗎居然1A啦???提交的時候只是想著先WA一次的。。。。
這題真的很妙啊
首先第一步,就是把僵屍的生命值取一個前綴和,這樣造成傷害的時候,可以視為同時對所有僵屍造成傷害。
那麽就可以得到一個柿子:
對於第i次進攻,k=max( (sum[i]-sum[j-1]) / x[i]+(i-j)*d ) 其中j表示第j只僵屍。
這樣時間的復雜度是O(n^2)的,妥妥的過不去
然後設y1=sum[i],y2=sum[j-1] x1=x[i]+i*d,x2=j*d
柿子就變成了k=(y1-y2)/(x1-x2)這不就是斜率嗎
令P(x1,y1),Q(x2,y2)可以發現Q一直是不變的,變的只是P,值得註意的是P的x坐標沒有單調性
那麽對於Q每次加入用單調棧維護一個下凸包,三分答案出解即可
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; double sum[110000],w[110000]; struct node { double x,y; }sta[110000];int top; double slope(node n1,node n2){return(n1.y-n2.y)/(n1.x-n2.x);} int main() { int n;double d; scanf("%d%lf",&n,&d); double ans=0; sum[0]=0;top=0; for(int i=1;i<=n;i++) { scanf("%lf%lf",&sum[i],&w[i]);sum[i]+=sum[i-1]; node Q; Q.x=double(i)*d,Q.y=sum[i-1];while(top!=0&&slope(sta[top-1],sta[top])>=slope(sta[top],Q))top--; sta[++top]=Q; node P; P.x=w[i]+double(i)*d,P.y=sum[i]; int l=1,r=top; while(r-l>3) { int mid=(l+r)/2; int mmid=(mid+r)/2; if(slope(P,sta[mid])>slope(P,sta[mmid])) { r=mmid-1; } else l=mid+1; } int ip=l; for(int j=l+1;j<=r;j++) if(slope(P,sta[j])>slope(P,sta[ip]))ip=j; ans+=slope(P,sta[ip]); } printf("%.0lf\n",ans); return 0; }
bzoj3203: [Sdoi2013]保護出題人