BZOJ 3203 [SDOI2013]保护出题人 (凸包+三分)

洛谷传送门

题目大意:太长略

每新加入一个僵尸,容易得到方程$ans[i]=max{\frac{sum_{i}-sum_{j-1}}{s_{i}+d(i-j)}}$

即从头开始每一段僵尸都需要在规定距离内被消灭

展开式子,可得$ans[i]=max{\frac{sum_{i}-sum_{j-1}}{s_{i}+di-dj}}$

是不是很像斜率的式子= = ----$(y2-y1)/(x2-x2)$

维护一个下凸包,这次不是用直线去切凸包,而是把凸包上每个点都向一个定点去连直线,求最大的斜率

会发现,凸包上连出来的直线的斜率是一个凸函数,再利用三分法进行查找

三分法类似于一个爬坡的过程,每次都缩小两侧山坡范围,最终找到山顶

至于为什么维护下凸包呢,画个图就明白了,如果之前某个点$a$,与点$b(b_{x}<a_{x})$的斜率,大于新加入的点$i$与$b$的斜率,那么如果右侧出现一个点,向他们连直线,显然$i$的斜率大于$a$,可以用三角形的性质去证

因为$x$递增,用单调栈维护下凸包即可

时间$O(nlogn)$

貌似比较斜率必须用$double$,不然爆$long\;long$

 1 #include <cmath>
 2 #include <queue>
 3 #include <vector>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 #define N1 101000
 8 #define M1 205
 9 #define ll long long
10 #define dd double  
11 #define uint unsigned int
12 using namespace std;
13 
14 ll gll()
15 {
16     ll ret=0;int fh=1;char c=getchar();
17     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
18     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
19     return ret*fh;
20 }
21 int n;
22 ll D;
23 ll a[N1],s[N1],sa[N1];
24 ll x[N1],y[N1];
25 int stk[N1],tp;
26 inline dd gslope(int i,int j){
27     return 1.0*(y[i]-y[j])/(x[i]-x[j]);
28 }
29 
30 int main()
31 {
32     //freopen("t2.in","r",stdin);
33     scanf("%d%lld",&n,&D);
34     for(int i=1;i<=n;i++)
35         a[i]=gll(),s[i]=gll(),sa[i]=sa[i-1]+a[i];
36     dd ans=0;
37     for(int i=1;i<=n;i++)
38     {
39         x[i]=1.0*i*D,y[i]=sa[i-1];
40         while(tp>1&&gslope(stk[tp],stk[tp-1])>=gslope(i,stk[tp-1]))
41             tp--;
42         stk[++tp]=i;
43         int l=1,r=tp,mid1,mid2;
44         x[0]=1.0*s[i]+1.0*D*i,y[0]=sa[i];
45         while(r-l>=3)
46         {
47             mid1=(l+l+r)/3,mid2=(l+r+r)/3;
48             if(gslope(0,stk[mid1])>gslope(0,stk[mid2]))
49                 r=mid2;
50             else 
51                 l=mid1;
52         }
53         dd ma=0;
54         for(int j=l;j<=r;j++)
55             ma=max(ma,gslope(0,stk[j]));
56         ans+=ma;
57     }
58     printf("%.0lf\n",ans);
59     return 0;
60 }

猜你喜欢

转载自www.cnblogs.com/guapisolo/p/10053358.html