7.10省队集训梦工厂

原创 2015年07月10日 15:23:06


思路:题面真心长....单调栈维护上凸壳即可

设sum[i]为前i道工序的复杂度之和,g[i]为第i个快乐最早开始生产的时间。因为我们要保证没有两个快乐同时出现在同一道工序,所以

g[i]=g[i-1]+max(sum[j]*f[i-1]-sum[j-1]*f[i])

然后就是像斜率优化的过程了

sum[j]*f[i-1]=f[i]*sum[j-1]+g[i]-g[i-1]

sum[j]=f[i]/f[i-1]*sum[j-1]+(g[i]-g[i-1])/f[i-1]

     y     =     k     *       x       +              b

于是可以发现使g[i]最大的点一定在一个上凸壳上,因为查询的斜率f[i]/f[i-1]不单调,用单调栈维护,二分查询即可。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define max(a,b) (a>b?a:b)
#define ll long long
const int maxn=2000010,inf=(int)1e9;
const double eps=1e-9;
using namespace std;
int n,m,sum[maxn],f[maxn],t[maxn],q[maxn],top;ll tim,g[maxn];char ch;
void read(int &x){
    for (ch=getchar();!isdigit(ch);ch=getchar());
    for (x=0;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
}
 
double slope(int i,int j){
    if (i==0||j==0) return inf;
    if (i==inf||j==inf) return -inf;
    return 1.0*(sum[i]-sum[j])/(double)(sum[i-1]-sum[j-1]);
}
 
void work(){
    q[1]=0,q[2]=1,top=2,q[top+1]=inf,g[1]=0;
    for (int i=2;i<=n;i++){
        for (;top&&slope(i,q[top])>slope(q[top],q[top-1])+eps;) {
            top--;
        }
        q[++top]=i,q[top+1]=inf;
    }
    for (int i=2;i<=m;i++){
        int l=1,r=top,mid=(l+r)>>1;double k=(1.0*f[i])/(1.0*f[i-1]);
        while (1){
            if (slope(q[mid],q[mid-1])+eps>=k&&slope(q[mid],q[mid+1])<=k+eps) break;
            else if (slope(q[mid],q[mid+1])>k+eps) l=mid+1;
            else r=mid-1;
            mid=(l+r)>>1;
        }
        g[i]=g[i-1]+(ll)sum[q[mid]]*f[i-1]-(ll)sum[q[mid]-1]*f[i];
    }
    printf("%lld\n",1ll*(g[m]+1ll*sum[n]*f[m]));
}
 
int main(){
    freopen("yume.in","r",stdin);freopen("yume.out","w",stdout);
    read(n),read(m);
    for (int i=1;i<=n;i++) read(t[i]),sum[i]=sum[i-1]+t[i];
    for (int i=1;i<=m;i++) read(f[i]);
    work();
    fclose(stdout);
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

2015湖南省队集训DAY8——梦工厂

梦工厂 (yume.cpp/c/pas)Time Limit: 1 s Memory Limit: 128 M 问题描述「有时候用烂了的名字也会别有深意」 ——摘自EN 语录 “这里是...

省队集训Round2 DAY3

T3 题解 要求每一个时间每条边只能有一个人经过,每个人在到达终点前的任意时刻都不能停止。 那么我们可以二分一个最晚的时间mid,然后建mid层结点,每条有向边x->y从i层的x结点...

[JZOJ5134][SDOI省队集训2017]三元组

题目大意求∑ai=1∑bj=1∑ck=1[(i,j)=1][(i,k)=1][(j,k)=1]\sum_{i=1}^a\sum_{j=1}^b\sum_{k=1}^c[(i,j)=1][(i,k)=1...

7.5省队集训 tree

Tree  【题目描述】  RHL 有一天看到 lmc 在玩一个游戏。  “愚蠢的人类哟,what are you doing”,RHL 说。  “我在玩一个游戏。现在这里有一个有 n 个结点的有根树...

jsoi2012省队集训:集合计数

【问题描述】 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007。(是质数哦...

省队集训Round2 DAY2

T3 题解 这道题以前做过一个静态的,就是树在开始的时候直接建好,后面直接查询。 这道题的关键是需要看出集合的构建实际上是一颗树结构,每次就是找到所以点的lca然后新加入的点就是lc...

[JZOJ5135][SDOI省队集训2017]逆序对

题目大意有多少n的排列逆序对个数为k?模型转化假设有一个i的排列,插入i+1逆序对个数会增加多少? 发现会增加0~i。 因此模型转化为,n个变量,0...

省队集训Round3 DAY4

T2 题解 讲序列分成三部分,大根堆,缓冲区s,小根堆。 任意时刻保证mid在缓冲区中,并且尽量保证大根堆和小根堆的大小尽量相等。 均摊时间复杂度为O(nlogn/s+n)O(nlog...

【互补松弛定理】12.7.16省队集训

互补松弛定理 sigma(aij*yi | i=1~m)==cj or xi=0 j=1,2...,n sigma(aij*xj | j=1~n)==bi or yi=0 i=1,2...m 题意:...

省队集训Round2 DAY7

T2 题解 考虑最暴力的做法,实际上就是枚举选中区间的左右端点,然后用点分判断选出的点构成的合法路径和未选中的点构成的合法路径的大小。 如果再优化一点可以,枚举其中一个端点,另一个端...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:7.10省队集训梦工厂
举报原因:
原因补充:

(最多只允许输入30个字)