zoukankan      html  css  js  c++  java
  • 【洛谷 P3299】 [SDOI2013]保护出题人 (凸包,三分,斜率优化)

    题目链接
    易得第(i)关的最小攻击力为(max_{j=1}^ifrac{sum[i]-sum[j-1]}{x+d*(i-j)})
    十分像一个斜率式,于是看作一个点(P(x+d*i,sum[i]))和点(Q(d*j,sum[j-1]))的斜率
    于是就是求当前(i)的点(P)和之前的所有点(Q)的最大斜率,显然有最大斜率的点在凸包上而且有单峰。
    于是用单调队列维护凸包,在凸包上三分斜率最大值。

    #include <cstdio>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int MAXN = 100010;
    inline ll read(){
        ll s = 0;
    	int w = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
        return s * w;
    }
    int n, top;
    ll d;
    ll a[MAXN], x[MAXN], sum[MAXN];
    int st[MAXN];
    double k(int i, int j){
    	return ((double)sum[i - 1] - sum[j - 1]) / (i * d - j * d);
    }
    double calc(int i, int j){
    	return ((double)sum[i] - sum[j - 1]) / (x[i] + d * (i - j));
    }
    double ans;
    int main(){
    	n = read(); d = read();
    	for(int i = 1; i <= n; ++i){
    	   a[i] = read(); x[i] = read();
    	   sum[i] = sum[i - 1] + a[i];
        }
        for(int i = 1; i <= n; ++i){
           while(top > 1 && k(st[top - 1], st[top]) > k(st[top - 1], i)) --top;
           st[++top] = i;
           int l = 1, r = top, mid1, mid2, p;
           while(l != r){
           	  p = (r - l + 1) / 3;
           	  mid1 = l + p - 1;
           	  mid2 = l + p + p - 1;
           	  if(mid1 == mid2) break;
           	  if(calc(i, st[mid1]) < calc(i, st[mid2])) l = mid1 + 1;
           	  else r = mid2 - 1;
           }
           ans += max(calc(i, st[l]), calc(i, st[r]));
        }
        printf("%.0lf
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    CSS实现雨滴动画效果
    大型网站架构系列:电商网站架构案例
    CSS 不定宽高的垂直水平居中方式总汇
    js中尺寸类样式
    Tiling
    排序二叉树
    算术表达式的转换
    Area
    catch that cow
    R中双表操作学习[转载]
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/10323485.html
Copyright © 2011-2022 走看看