题解

我写的斜率维护,放弃了我最擅长的叉积维护,然后发现叉积维护也不会爆long long哦……

一写斜率维护我的代码就会莫名变长而且难写……行吧

我们看这题
推了推式子,发现这是个斜率的式子,但是斜率单增还要求最大值?啥我又得二分凸包……好烦……

然后我们求一个pre[x]表示[1,x]的最大分数,和一个suf[x]表示[x,N]里的最大分数

然后对于一个点枚举一个包含它的区间,计算取值

显然超时

那就放在分治上,左端点在左区间,右端点在右区间,把最大值处理成前后缀max,两边都是斜率优化

挺好想的,二分凸包的判断条件想起来有点别扭,写起来有点难受

但是题目挺有意思的

但是题解我是懒得写的= =
为什么,因为我颓……

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define fi first
#define se second
#define pii pair<int,int>
//#define ivorysi
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 300005
using namespace std;
typedef long long int64;
typedef double db;
typedef unsigned int u32;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9' ) {
        res = res * 10 + c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
        out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,M;
int64 T[MAXN],pre[MAXN],suf[MAXN],sum[MAXN],ans[MAXN],cal[MAXN];
struct Point {
    int64 x,y;
    Point(){}
    Point(int64 _x,int64 _y) {
        x = _x;y = _y;
    }
}que[MAXN],pre_pos[MAXN],suf_pos[MAXN];
struct qry_node {
    int id,pos;
    int64 v;
}qry[MAXN],tmp1[MAXN],tmp2[MAXN];
bool slope(Point a,Point b,Point c) {
    return (c.y - b.y) * (b.x - a.x) > (b.y - a.y) *  (c.x - b.x);
}
void DC(int l,int r,int ql,int qr) {
    if(qr < ql) return;
    if(l == r) return;
    int mid = (l + r) >> 1;
    int tot = 0;
    que[++tot] = pre_pos[l - 1];
    for(int i = l ; i <= mid ; ++i) {
        while(tot > 1) {
            if(slope(que[tot - 1],que[tot],pre_pos[i])) --tot;
            else break;
        }
        que[++tot] = pre_pos[i];
    }
    for(int i = r + 1 ; i >= mid + 2; --i) {
        int L = 1,R = tot;
        while(L < R) {
            int mid = (L + R) >> 1;
            if((que[mid + 1].y - que[mid].y) >= 1LL * i * (que[mid + 1].x - que[mid].x))
                L = mid + 1;
            else R = mid;
        }
        L = que[L].x;
        cal[i] = suf[i] + pre[L] - sum[i - 1] + sum[L] + 1LL * (i - L - 1) * (i - L) / 2;
    }
    tot = 0;
    que[++tot] = suf_pos[r + 1];
    for(int i = r ; i > mid ; --i) {
        while(tot > 1) {
            if(slope(suf_pos[i],que[tot],que[tot - 1])) --tot;
            else break;
        }
        que[++tot] = suf_pos[i];
    }
    for(int i = l - 1 ; i < mid ; ++i) {
        int L = 1,R = tot;
        while(L < R) {
            int mid = (L + R) >> 1;
            if((que[mid].y - que[mid + 1].y) >= 1LL * i * (que[mid].x - que[mid + 1].x))
                R = mid;
            else L = mid + 1;
        }
        L = que[L].x;
        cal[i] = pre[i] + suf[L] - sum[L - 1] + sum[i] + 1LL * (L - i - 1) * (L - i) / 2;
    }
    for(int i = l ; i < mid ; ++i) cal[i] = max(cal[i - 1],cal[i]);
    for(int i = r ; i > mid + 1 ; --i) cal[i] = max(cal[i + 1],cal[i]);
    int t1 = 0,t2 = 0;
    for(int i = ql ; i <= qr ; ++i) {
        if(qry[i].pos <= mid) {
            ans[qry[i].id] = max(ans[qry[i].id],cal[qry[i].pos - 1] + T[qry[i].pos] - qry[i].v);
            tmp1[++t1] = qry[i];
        }
        else {
            ans[qry[i].id] = max(ans[qry[i].id],cal[qry[i].pos + 1] + T[qry[i].pos] - qry[i].v);
            tmp2[++t2] = qry[i];
        }
    }
    int p = ql - 1;
    for(int i = 1 ; i <= t1 ; ++i) qry[++p] = tmp1[i];
    for(int i = 1 ; i <= t2 ; ++i) qry[++p] = tmp2[i];
    DC(l,mid,ql,ql + t1 - 1);
    DC(mid + 1,r,ql + t1,qr);
}   

void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(T[i]);
    for(int i = 1 ; i <= N ; ++i) sum[i] = sum[i - 1] + T[i];
    int tot = 0;
    que[++tot] = Point(0,0);
    for(int i = 1 ; i <= N ; ++i) {
        int l = 1,r = tot;
        while(l < r) {
            int mid = (l + r) >> 1;
            if((que[mid + 1].y - que[mid].y) >= 1LL * i * (que[mid + 1].x - que[mid].x))
                l = mid + 1;
            else r = mid;
        }
        l = que[l].x;
        pre[i] = pre[l] + 1LL * (i - l) * (i - l + 1) / 2 - sum[i] + sum[l];
        pre[i] = max(pre[i],pre[i - 1]);
        Point p = Point(i,pre[i] + sum[i] + (1LL * i * (i - 1)) / 2);
        while(tot > 1) {
            if(slope(que[tot - 1],que[tot],p)) --tot;
            else break;
        }
        que[++tot] = p;
    }
    tot = 0;
    que[++tot] = Point(N + 1,(1LL * (N + 1) * (N + 2) / 2) - sum[N]);
    for(int i = N ; i >= 1 ; --i) {
        int l = 1,r = tot;
        while(l < r) {
            int mid = (l + r) >> 1;
            if((que[mid].y - que[mid + 1].y) >= 1LL * i * (que[mid].x - que[mid + 1].x))
                r = mid;
            else l = mid + 1;
        }
        l = que[l].x;
        suf[i] = suf[l] + (1LL * (l - i + 1) * (l - i) / 2) - sum[l - 1] + sum[i - 1];
        suf[i] = max(suf[i],suf[i + 1]);
        Point p = Point(i,suf[i] - sum[i - 1] + (1LL * i * (i + 1) / 2));
        while(tot > 1) {
            if(slope(p,que[tot],que[tot - 1])) --tot;
            else break;
        }
        que[++tot] = p;
    }
    for(int i = 0 ; i <= N ; ++i) {
        pre_pos[i] = Point(i,pre[i] + sum[i] + (1LL * i * (i + 1) / 2));
    }
    for(int i = 1 ; i <= N + 1 ; ++i) {
        suf_pos[i] = Point(i,suf[i] - sum[i - 1] + (1LL * i * (i - 1) / 2));
    }
    read(M);
    int p;int64 v;
    for(int i = 1 ; i <= M ; ++i) {
        read(p);read(v);
        qry[i] = (qry_node){i,p,v};
        ans[i] = pre[p - 1] + suf[p + 1];
    }
    DC(1,N,1,M);
    for(int i = 1 ; i <= M ; ++i) {
        out(ans[i]);enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

【ARC066】F - Contest with Drinks Hard的更多相关文章

  1. 【POJ】【2187】Beauty Contest

    计算几何/旋转卡壳 学习旋转卡壳请戳这里~感觉讲的最好的就是这个了…… 其实就是找面积最大的三角形?...并且满足单调…… 嗯反正就是这样…… 这是一道模板题 好像必须写成循环访问?我在原数组后面复制 ...

  2. 【python】f.write()写入中文出错解决办法

    一个出错的例子 #coding:utf-8 s = u'中文' f = open("test.txt","w") f.write(s) f.close() 原因 ...

  3. 【poj2187】 Beauty Contest

    http://poj.org/problem?id=2187 (题目链接) 题意 求点集上两点间最长距离 Solution 凸包+旋转卡壳. 旋转卡壳是看起来很难,但是很好意会也很好实现的算法,但是要 ...

  4. MT【248】$f(x)=\dfrac{1}{x-1}+\dfrac{1}{x-b}$的性质

    探讨函数$f(x)=\dfrac{1}{x-a}+\dfrac{1}{x-b}$其中$a<b$的几个性质 分析:对称性:关于$(\dfrac{a+b}{2},0)$证明提示:$f(x)+f(a+ ...

  5. AtCoder Regular Contest 066 F Contest with Drinks Hard

    题意: 你现在有n个题目可以做,第i个题目需要的时间为t[i],你要选择其中的若干题目去做.不妨令choose[i]表示第i个题目做不做.定义cost=∑(i<=n)∑(i<=j<= ...

  6. 【HDU4734】F(x) 【数位dp】

    题意 先定义了一个函数F(X)=An*2^n-1+An-1*2^n-2+.....+A1*1.其中Ai为X的第i位的值.对于每组数据给出了两个整数A,B.问不超过B的数中有多少的F值是不超过F(A)的 ...

  7. 【hdu4734】F(x) 数位dp

    题目描述 对于一个非负整数 $x=​​\overline{a_na_{n-1}...a_2a_1}$ ,设 $F(x)=a_n·2^{n-1}+a_{n-1}·2^{n-2}+...+a_2·2^1+ ...

  8. 【数位dp入门】【HDU4734】F(x)

    记录减的状态,表示还要凑多少才能达到当前值. 然后进行枚举即可.注意状态数不能重复. #include<bits/stdc++.h> #define N 10010 using names ...

  9. 【cf995】F. Cowmpany Cowmpensation(拉格朗日插值)

    传送门 题意: 给出一颗树,每个结点有取值范围\([1,D]\). 现在有限制条件:对于一个子树,根节点的取值要大于等于子数内各结点的取值. 问有多少种取值方案. 思路: 手画一下发现,对于一颗大小为 ...

随机推荐

  1. [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

    转载自:https://segmentfault.com/a/1190000006435886 解决办法:添加package.config.js配置文件中,添加本文章的红色部分代码 import vu ...

  2. android onActivityResult的执行

    1.如果activity中重写了onActivityResult函数,同时添加在该activity的fragment也重写了onActivtyResult函数,那么会执行Activity的onActi ...

  3. What Does “Neurons that Fire Together Wire Together” Mean?

    What Does “Neurons that Fire Together Wire Together” Mean? I’ve heard the phrase “neurons that fire ...

  4. Java并发编程原理与实战九:synchronized的原理与使用

    一.理论层面 内置锁与互斥锁 修饰普通方法.修饰静态方法.修饰代码块 package com.roocon.thread.t3; public class Sequence { private sta ...

  5. dubbo Filter

    官方说明: 调用拦截扩展 扩展说明 服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响. 约定: 用户自定义 fi ...

  6. Python核心编程——Chapter9

    好久没写过Python了,前一阵子忙这忙那的,都几乎把Python给丢掉了,话不多说,马上开始. 9.1.文件过滤.显示一个文件的所有行,并且忽略以井号开头的行. 其实这个题目比较基础,用shell语 ...

  7. 微服务深入浅出(10)-- Docker

    概念 1.Docker引擎 一个运行在服务器上的后台进程 2.Docker客户端 分为两种:CLI和RestAPI,与Docker引擎交互 3.Docker镜像 类似于我们使用的光盘,将程序打包到Do ...

  8. Linux Shell管道调用用户定义函数(使shell支持map函数式特性)

    Linux中有一个管道的概念,常用来流式的处理文本内容,比如一个文件对其中的每一行应用好几个操作,出于两个方面的考虑可能需要在管道中使用用户定义函数: 1. 刚需: 内置的sed/awk之类的可能没法 ...

  9. 【CTF WEB】GCTF-2017读文件

    读文件 只给了个1.txt可以读,试了一下加*不行,感觉不是命令执行,"../"返回上级目录也不行,猜测可能过滤了什么,在1.txt中间加上"./"发现仍能读取 ...

  10. STM32 IAP升级

    STM32 IAP在线升级,用Jlink设置读保护后前5K字节是默认加了写保护的,导致IAP升级时擦除和写入FLASH不成功,可以做两个boot,前5k为第一个boot程序,上电时负责跳转到APP还是 ...