zoukankan      html  css  js  c++  java
  • [SDOI2012]任务安排

    XII.[SDOI2012]任务安排

    同上一题一样,不过,这题的\(t_i\)可能有负数,这就意味着前缀和不再是单调增的!

    我们不能再像前一题一样用单调队列维护了——但是因为队尾的单调性仍然存在,我们仍然可以维护上凸包。这就启发我们使用单调栈来维护斜率,并且在单调栈中二分。

    我们不妨想一想,如果这个\(c\)也有可能是负数怎么办?

    \(c\)是负数就意味着不再具有一个明确的凸壳——我们在两边同除时不知道\(c[j]-c[k]\)是正是负。因此,我们可以采用平衡树来支持插入斜率和查询,复杂度\(O(n\log n)\)。(该方法纯属口胡,请勿当真)

    本题代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int n,m,t[300100],c[300100],f[300100],s[300100],tp;
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%lld%lld",&t[i],&c[i]),t[i]+=t[i-1],c[i]+=c[i-1];
    	for(int i=1;i<=n;i++){
    		int L=0,R=tp;
    		while(L<R){
    			int mid=(L+R)>>1;
    			if((f[s[mid]]-f[s[mid+1]])>=(c[s[mid]]-c[s[mid+1]])*(m+t[i]))L=mid+1;
    			else R=mid;
    		}
    		f[i]=f[s[L]]+m*(c[n]-c[s[L]])+t[i]*(c[i]-c[s[L]]);
    		while(tp&&(f[s[tp-1]]-f[s[tp]])*(c[s[tp]]-c[i])>=(f[s[tp]]-f[i])*(c[s[tp-1]]-c[s[tp]]))tp--;
    		s[++tp]=i;
    	}
    	printf("%lld\n",f[n]);
    	return 0;
    }
    

  • 相关阅读:
    Android开机自启动应用
    扫码登录原理
    前端性能优化
    关于android推送的一些心得
    抓包工具Fiddler及iphone设置
    Node.js介绍、优势、用途
    Yapi本地化部署及接口调试(亲测)
    前后端分离,几个常用的API管理系统
    WebGL之Threejs概述
    Eclipse汉化
  • 原文地址:https://www.cnblogs.com/Troverld/p/14596868.html
Copyright © 2011-2022 走看看