bzoj 1096: [ZJOI2007]仓库建设

和刚做的一样,写出一个f[i]分别从f[j],f[k](i>j>k)的方程,然后令f[j]<f[k],得到的是一个f[j]-f[k]<cost(i,k)-cost(i,j),然后可以发现每个点到i的价值可以用x[i]*p[j]-x[j]*p[j]的到,那么都写出来,提一下x[i],就可以把p[j],和p[j]*x[j]搞一个前缀和来维护啦。

(这些题还是都开了LL靠谱。。)

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 #define lowbit(x) x&(-x)
 4 #define inf 0x3f3f3f3f
 5 #define eps 1e-5
 6 #define N 1000005
 7 using namespace std;
 8 inline int ra()
 9 {
10     int x=0,f=1; char ch=getchar();
11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
13     return x*f;
14 }
15 LL f[N],cst[N],a[N];
16 int x[N],p[N],c[N],q[N];
17 int n;
18 double slope(int j, int k)
19 {
20     return (double)(f[j]-f[k]+(a[j]-a[k]))/(double)(cst[j]-cst[k]);
21 }
22 int main(int argc, char const *argv[])
23 {
24     n=ra();
25     for (int i=1; i<=n; i++) x[i]=ra(),p[i]=ra(),c[i]=ra();
26     for (int i=1; i<=n; i++) cst[i]=p[i]+cst[i-1];
27     for (int i=1; i<=n; i++) a[i]=a[i-1]+p[i]*x[i];
28     int l=0,r=0;
29     for (int i=1; i<=n; i++)
30     {
31         while (l<r && slope(q[l+1],q[l])<x[i]) l++;
32         int t=q[l];
33         f[i]=f[t]+c[i]+x[i]*(cst[i]-cst[t])-(a[i]-a[t]);
34         while (l<r && slope(i,q[r])<slope(q[r],q[r-1])) r--;
35         q[++r]=i;
36     }
37     cout<<f[n];
38     return 0; 
39 }

 

posted @ 2017-03-08 21:02  ws_ccd  阅读(141)  评论(0编辑  收藏  举报