线段树分治套凸包

每个机器人在多次修改之间的贡献是不同的,因为这个一次函数被修改。显然要线段树分治。

我们需要在线段树上维护凸壳,刚开始我以为要用动态凸包的那套理论。后来才知道直接在外面给所有一次函数排序,做凸壳就能是线性的了。。。我真智障

这个代码常数太大,在UOJ上排倒二,你们还是别(另)看(请)了(高)吧(明)。

#include<cstdio>
#include<algorithm>
#define N 500005
#define cmax(u,v) (u)<(v)?(u)=(v):0
using namespace std;
namespace ziqian
{typedef long long ll;const int INF = 1<<29;int in(){int r = 0, p = 0; char c = getchar();for(; c < '0' || c > '9'; c = getchar()) if(c == '-') p = 1;for(; c >='0' && c <='9'; c = getchar()) r = r * 10 + c - '0';return p?-r:r;  }struct line{int k; ll b;ll f(int x) {return (ll)k * x + b;}double operator * (line l){return (double)(b-l.b)/(l.k-k);}}con[N];struct modify{line L; int l, r;} mod[N*2], tmp_mod[N*2];ll ans[N];int n, m, last[N], tot, qcnt, q[N];char s[10];double px[N];bool cmp(modify a, modify b){return a.L.k < b.L.k;}void solve(int ml, int mr, int ql, int qr){if(ml > mr) return;int top = 0;for(int i = ml; i <= mr; i++)if(mod[i].l <= ql && qr <= mod[i].r){line L = mod[i].L;while(top > 1){if(con[top].k == L.k){if(con[top].b <= L.b) --top;else break;}else if(L * con[top] <= con[top-1] * con[top])--top;else break;}if(!(con[top].k == L.k && con[top].b >= L.b))con[++top] = L;}for(int i = 1; i < top; i++) px[i] = con[i] * con[i+1];px[top] = INF;for(int i = ql, cur = 1; cur <= top && i <= qr; i++){for(; px[cur] < q[i] && cur <= top; ++cur);if(cur > top)break;ll tmp = con[cur].f(q[i]);cmax(ans[i], tmp);}if(ql == qr)return;int mid = (ql+qr)>>1, nl = ml-1, nr = mr+1;for(int i = ml; i <= mr; i++){if(mod[i].l <= mid && (mod[i].l > ql || qr > mod[i].r)) ++nl, tmp_mod[nl] = mod[i];else --nr, tmp_mod[nr] = mod[i];}for(int i = nr, ii = (nr+mr)/2; i <= ii; i++) swap(tmp_mod[i], tmp_mod[nr+mr-i]);for(int i = ml; i <= mr; i++) mod[i] = tmp_mod[i];solve(ml, nl, ql, mid);int ll = nl+1, tmpcnt = ml-1;for(int i = ml; i <= nl || ll <= mr; ){if(ll > mr ||( i <= nl && mod[i].L.k < mod[ll].L.k)) tmp_mod[++tmpcnt] = mod[i], i++;else tmp_mod[++tmpcnt] = mod[ll], ll++;}for(int i = ml; i <= mr; i++) mod[i] = tmp_mod[i];nl = ml - 1; nr = mr + 1;for(int i = ml; i <= mr; i++){if(mod[i].r > mid && (mod[i].l > ql || qr > mod[i].r)) ++nl, tmp_mod[nl] = mod[i];else --nr, tmp_mod[nr] = mod[i];}for(int i = nr, ii = (nr+mr)/2; i <= ii; i++) swap(tmp_mod[i], tmp_mod[nr+mr-i]);for(int i = ml; i <= mr; i++) mod[i] = tmp_mod[i];solve(ml, nl, mid+1,qr);ll = nl+1, tmpcnt = ml-1;for(int i = ml; i <= nl || ll <= mr; ){if(ll > mr ||( i <= nl && mod[i].L.k < mod[ll].L.k)) tmp_mod[++tmpcnt] = mod[i], i++;else tmp_mod[++tmpcnt] = mod[ll], ll++;}for(int i = ml; i <= mr; i++) mod[i] = tmp_mod[i];}void main(){n = in(), m = in();for(int i = 1; i <= n; i++) {mod[++tot] = (modify){(line){0, in()}, 1, -1};last[i] = tot;}for(int i = 1, t; i <= m; i++){t = in(); scanf("%s",s);if(s[0] == 'c') {int pos = in(), kk = in();mod[last[pos]].r = qcnt; mod[++tot] = (modify){(line){kk, mod[last[pos]].L.f(t) - (ll)kk * t}, qcnt+1, -1};last[pos] = tot;}elseq[++qcnt] = t;}for(int i = 1; i <= tot; i++) if(mod[i].r == -1) mod[i].r = qcnt;for(int i = 1; i <= tot; i++) if(mod[i].l > mod[i].r)mod[i] = mod[tot--];sort(mod+1,mod+1+tot,cmp);  solve(1, tot, 1, qcnt); for(int i = 1; i <= tot; i++)mod[i].L.k *= -1, mod[i].L.b *= -1;sort(mod+1,mod+1+tot,cmp);  solve(1, tot, 1, qcnt);for(int i = 1; i <= qcnt; i++)printf("%lld\n",ans[i]);}
}
int main()
{ziqian::main();
}

UOJ 88 [集训队互测2015]Robot相关推荐

  1. BZOJ3938 UOJ88:[集训队互测2015]Robot——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3938 http://uoj.ac/problem/88 小q有n只机器人,一开始他把机器人放在了一 ...

  2. 【uoj#94】【集训队互测2015】胡策的统计(集合幂级数)

    题目传送门:http://uoj.ac/problem/94 这是一道集合幂级数的入门题目.我们先考虑求出每个点集的连通生成子图个数,记为$g_S$,再记$h_S$为点集$S$的生成子图个数,容易发现 ...

  3. [Luogu5042/UOJ #100][国家集训队互测2015]丢失的题面/ydc的题面

    题目链接: Luogu5042 UOJ #100 最近有点颓..然后就打算找Duliu做 然后就有了这篇题解..(虽然基本上都是抄的 \(Task1\) 输入\(22\),输出为长度为\(2^{22} ...

  4. 【集训队互测2015】最大异或和

    首先不知道有没有神仙线段树分治过的. 首先一个较为显然的性质: \[ \mathrm{Span}\{v_1, v_2, \dots, v_n\} = \mathrm{Span}\{v_1, v_2 - ...

  5. [2015国家集训队互测]口胡

    比赛链接 http://uoj.ac/contest/11 口胡题解 A.[集训队互测2015]Robot 直接果断打暴力了...这个暴力很好写,我就不废话了 B.[集训队互测2015]Marketi ...

  6. UOJ#191. 【集训队互测2016】Unknown

    UOJ#191. [集训队互测2016]Unknown 题目描述 Solution 二进制分组. 每一个组内维护一个斜率单调减的凸包. 因为有删点,避免出现反复横跳产生的爆炸复杂度,需要等到同一深度的 ...

  7. 「2019 集训队互测 Day 1」最短路径 解题报告

    一.题目概述 题目链接:Libre OJ. 给出一张图,求出 ans=∑i=1n∑j=1n[i≠j]dk(i,j)ans=\sum_{i=1}^n\sum_{j=1}^n[i\ne j]\texttt ...

  8. 【LOJ3077】「2019 集训队互测 Day 4」绝目编诗

    [题目链接] 点击打开链接 [思路要点] 不难发现各个边双连通分量可以分开处理,桥边可以直接删除. 可以证明,对于每一个边双连通分量,当 M−NM-NM−N 超过 O(N)O(\sqrt{N})O(N ...

  9. 洛谷 P4463 [集训队互测 2012] calc(拉格朗日插值优化DP)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/P4463 Prob ...

最新文章

  1. OpenAI新论文称打败GAN达到SOTA!是噱头还是干货?
  2. linux中sudo如何读取标准输入作为密码,避免每次都输入密码?
  3. 解决go包管理代理网址无法访问:proxy.golang.org 换成goproxy.cn
  4. 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
  5. GitHub 新出的 Actions 是什么? 用他做自动测试?
  6. 计算机网络【六】网络层协议
  7. andriod开发增加一个菜单
  8. 希尔排序java实现
  9. mac cad石材填充图案_CAD怎么填充颜色?
  10. request.getcontextPath() 理解
  11. gtest简短,简单易用
  12. cuda和cudnn各版本下载地址
  13. cad快捷栏怎么调出来_cad工具栏怎么调出来
  14. 筛数方法相关系数_EXCEL中如何求一组数据的相关系数
  15. 华罗庚黄金分割优选法
  16. linux ios开发环境,iOS开发环境搭建(Linux版)
  17. LoadLibrary动态加载dll失败,GetLastError返回错误码126
  18. 关于高速光耦6n137的使用总结_高速光耦6n137典型应用电路图汇总(多谐振荡/光电隔离器/光耦开关) - 全文...
  19. Jaca定时任务-01-进程级别的Timer,ScheduledExecutorService,springtask
  20. RTKLIB专题学习(七)---精密单点定位实现初识(三)

热门文章

  1. 基于番茄土豆的scrum工时估计方法尝试
  2. GitHub下载网速太慢-解决方案
  3. MipMap的LOD实现原理
  4. Springboot 整合Swagger3 和 Knife4j
  5. Fusion360学习记录:虎符
  6. Activity——两个Activity之间的通信
  7. 计算机应用与软件 订阅,《计算机应用与软件》杂志_网上订阅-C刊导航网
  8. 复选框的全选,取消和反选
  9. CSS 实现各种 Loading 效果
  10. android分屏底层实现,Android 7.0分屏原理及生命周期