传送门

考虑用 \(segment~tree~beats\) 那一套理论,维护区间最小值 \(mn\) 和严格次小值 \(se\)

那么可以直接 \(mlog^2n\) 维护前三个操作

考虑维护历史最小值,先维护历史最小标记

写了写发现 \(max\) 那个修改不好操作

对于 \(max\) 操作来说,只会在 \(mn< v <se\) 的时候打上标记

这就相当于区间内等于 \(mn\) 的权值都要变成 \(v\)

那么 \(max\) 操作就可以变成对区间最小值的加法操作

而 \(v<se\),这样就可以非常方便维护历史最小值了

具体来说,维护下面几个标记

  1. 区间最小值的加法标记
  2. 区间其它值的加法标记
  3. 区间最小值的历史最小的加法标记
  4. 区间其它值的历史最小的加法标记

    下放的时候判断一下是否是区间最小值就好了
# include <bits/stdc++.h>
using namespace std;
typedef long long ll; namespace IO {
const int maxn(1 << 21 | 1); char obuf[maxn], ibuf[maxn], *iS, *iT, c, *oS = obuf, *oT = obuf + maxn - 1, st[60];
int f, tp; inline char Getc() {
return iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++;
} template <class Int> inline void In(Int &x) {
for (c = Getc(), f = 1; c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
for (x = 0; c >= '0' && c <= '9'; c = Getc()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= f;
} inline void Flush() {
fwrite(obuf, 1, oS - obuf, stdout);
oS = obuf;
} inline void Putc(char c) {
*oS++ = c;
if (oS == oT) Flush();
} template <class Int> inline void Out(Int x) {
if (x < 0) Putc('-'), x = -x;
if (!x) Putc('0');
while (x) st[++tp] = x % 10 + '0', x /= 10;
while (tp) Putc(st[tp--]);
}
} using IO :: In;
using IO :: Out;
using IO :: Putc;
using IO :: Flush; const int maxn(2e6 + 5);
const int inf(2e9); struct Min {
int mn1, mn2; inline Min operator +(Min b) const {
Min c;
c.mn1 = min(mn1, b.mn1), c.mn2 = min(mn2, b.mn2);
if (b.mn1 ^ c.mn1) c.mn2 = min(c.mn2, b.mn1);
if (mn1 ^ c.mn1) c.mn2 = min(c.mn2, mn1);
return c;
}
}; Min mn[maxn];
int n, m, hmn[maxn], addmn1[maxn], addmn2[maxn], addhmn1[maxn], addhmn2[maxn]; inline void Update(int x) {
mn[x] = mn[x << 1] + mn[x << 1 | 1], hmn[x] = min(hmn[x << 1], hmn[x << 1 | 1]);
} void Build(int x, int l, int r) {
int mid;
if (l == r) {
In(mn[x].mn1), mn[x].mn2 = inf, hmn[x] = mn[x].mn1;
return;
}
mid = (l + r) >> 1;
Build(x << 1, l, mid), Build(x << 1 | 1, mid + 1, r);
Update(x);
} inline void Puttag(int x, int vmn1, int vmn2, int vhmn1, int vhmn2) {
hmn[x] = min(hmn[x], mn[x].mn1 + vhmn1);
addhmn1[x] = min(addhmn1[x], addmn1[x] + vhmn1);
addhmn2[x] = min(addhmn2[x], addmn2[x] + vhmn2);
addmn1[x] += vmn1, addmn2[x] += vmn2, mn[x].mn1 += vmn1;
if (mn[x].mn2 ^ inf) mn[x].mn2 += vmn2;
} inline void Pushdown(int x) {
if (!addmn1[x] && !addmn2[x] && !addhmn1[x] && !addhmn2[x]) return;
int ls, rs, now;
ls = x << 1, rs = x << 1 | 1, now = min(mn[ls].mn1, mn[rs].mn1);
if (now == mn[ls].mn1) Puttag(ls, addmn1[x], addmn2[x], addhmn1[x], addhmn2[x]);
else Puttag(ls, addmn2[x], addmn2[x], addhmn2[x], addhmn2[x]);
if (now == mn[rs].mn1) Puttag(rs, addmn1[x], addmn2[x], addhmn1[x], addhmn2[x]);
else Puttag(rs, addmn2[x], addmn2[x], addhmn2[x], addhmn2[x]);
addmn1[x] = addmn2[x] = addhmn1[x] = addhmn2[x] = 0;
} void Modify_add(int x, int l, int r, int ql, int qr, int v) {
int mid;
if (ql <= l && qr >= r) {
Puttag(x, v, v, v, v);
return;
}
mid = (l + r) >> 1, Pushdown(x);
if (ql <= mid) Modify_add(x << 1, l, mid, ql, qr, v);
if (qr > mid) Modify_add(x << 1 | 1, mid + 1, r, ql, qr, v);
Update(x);
} void Modify_max(int x, int l, int r, int ql, int qr, int v) {
int mid;
if (mn[x].mn1 >= v) return;
if (ql <= l && qr >= r && mn[x].mn2 > v) {
Puttag(x, v - mn[x].mn1, 0, v - mn[x].mn1, 0);
return;
}
mid = (l + r) >> 1, Pushdown(x);
if (ql <= mid) Modify_max(x << 1, l, mid, ql, qr, v);
if (qr > mid) Modify_max(x << 1 | 1, mid + 1, r, ql, qr, v);
Update(x);
} int Query_min(int x, int l, int r, int ql, int qr) {
int mid, ret;
if (ql <= l && qr >= r) return mn[x].mn1;
mid = (l + r) >> 1, Pushdown(x), ret = inf;
if (ql <= mid) ret = Query_min(x << 1, l, mid, ql, qr);
if (qr > mid) ret = min(ret, Query_min(x << 1 | 1, mid + 1, r, ql, qr));
Update(x);
return ret;
} int Query_hmin(int x, int l, int r, int ql, int qr) {
int mid, ret;
if (ql <= l && qr >= r) return hmn[x];
mid = (l + r) >> 1, Pushdown(x), ret = inf;
if (ql <= mid) ret = Query_hmin(x << 1, l, mid, ql, qr);
if (qr > mid) ret = min(ret, Query_hmin(x << 1 | 1, mid + 1, r, ql, qr));
Update(x);
return ret;
} int main() {
int i, op, l, r, v;
In(n), In(m), Build(1, 1, n);
while (m) {
--m, In(op), In(l), In(r);
if (op == 1) In(v), Modify_add(1, 1, n, l, r, v);
else if (op == 2) In(v), Modify_max(1, 1, n, l, r, v);
else if (op == 3) Out(Query_min(1, 1, n, l, r)), Putc('\n');
else Out(Query_hmin(1, 1, n, l, r)), Putc('\n');
}
return Flush(), 0;
}

UOJ169. 【UR #11】元旦老人与数列的更多相关文章

  1. 2018.07.28 uoj#169. 【UR #11】元旦老人与数列(线段树)

    传送门 线段树好题. 维护区间加,区间取最大值,维护区间最小值,历史区间最小值. 同样先考虑不用维护历史区间最小值的情况,这个可以参考这道题的解法,维护区间最小和次小值可以解决前两个操作,然后使用历史 ...

  2. uoj169:元旦老人与数列

    题意:http://uoj.ac/problem/169 sol  :线段树..........蜜汁TLE了一个点,不管了..... 代码抄snowMyDream的,orz........... 线段 ...

  3. 【UOJ#169】元旦老人与数列

    论文题. 考虑到这题的维护和区间操作是反向的,也就是说无法像V那题快速的合并标记. 我们知道,一个区间的最小值和其他值是可以分开来维护的,因为如果一个区间被整体覆盖,那么最小值始终是最小值. 对于被覆 ...

  4. [UOJ #167]【UR #11】元旦老人与汉诺塔

    题目大意:给你一个有$n$个盘子的汉诺塔状态$S$,问有多少种不同的操作方法,使得可以在$m$步以内到达状态$T$.$n,m\leqslant100$ 题解:首先可以知道的是,一个状态最多可以转移到其 ...

  5. UR11 A.元旦老人与汉诺塔

    题目:http://uoj.ac/contest/23/problem/167 如果我们拿个map来存状态的话.设当前状态是v,下一个状态是s.有f[i+1][s]+=f[i][v]. 初始f[0][ ...

  6. UOJ.52.[UR #4]元旦激光炮(交互 思路)

    题目链接 \(Description\) 交互库中有三个排好序的,长度分别为\(n_a,n_b,n_c\)的数组\(a,b,c\).你需要求出所有元素中第\(k\)小的数.你可以调用至多\(100\) ...

  7. 【uoj#51】[UR #4]元旦三侠的游戏 博弈论+dp

    题目描述 给出 $n$ 和 $m$ ,$m$ 次询问.每次询问给出 $a$ 和 $b$ ,两人轮流选择:将 $a$ 加一或者将 $b$ 加一,但必须保证 $a^b\le n$ ,无法操作者输,问先手是 ...

  8. 网路流 uoj 168 元旦老人与丛林

    http://uoj.ac/problem/168 没想到是网络流 官方题解地址 http://jiry-2.blog.uoj.ac/blog/1115 subtask2告诉我们度数为012的点对答案 ...

  9. uoj167 元旦老人与汉诺塔(记忆化搜索)

    QwQ太懒了,题目直接复制uoj的了 QwQ这个题可以说是十分玄学的一道题了 首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动 不多解释了,不过实现起来还是有一点点难度的 直接 ...

随机推荐

  1. docker微服务部署之:四、安装docker、docker中安装mysql和jdk1.8、手动构建镜像、部署项目

    docker微服务部署之:三,搭建Zuul微服务项目 1.Centos7安装Docker 详见:Centos7安装Docker 2.Docker中安装jdk1.8 详见:使用Docker构建jdk1. ...

  2. java简单工厂设计模式

    一.基本定义 /* *简单工厂设计模式: *文字描述理解: * 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式. * 通过专门定义一个类来负责创建其它类的实例,被创建的实例通常 * 都具有共同 ...

  3. psp0级报告

    计划 1.1需求描述: 现在市场上有很多的面向小学生的题卡,但是这习题卡不但价格昂贵,而且每次做题的内容基本都是固定.针对这些问题,开发出了这款网页在线答题系统,每次的题目都有所不同,可以跟快更好提高 ...

  4. 祝福csdn回望2014,展望2015 大致可以这样总结和展望

    祝福CSDN回望2014,展望2015 大致可以这样总结和展望 回望2014,大致可以这样总结: 从寻觅一架飞机开始,到寻觅另一架飞机结束,中间觅了几天金正恩. 全年都在寻觅收钱的人.送钱的人和带着钱 ...

  5. 用jquery来实现类似“网易新闻”横向标题滑动的移动端页面

    HTML: <div id="navbar"> <div id='navbar_content' style="left:0px;"> ...

  6. c++ 网络编程课设入门超详细教程 ---目录

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9663167.html c++ 网络编程(一)TCP/UDP windows/linux 下入门 ...

  7. VMware虚拟机配置

    VMware虚拟机配置 背景 在做学习Linux时经常会在win环境下安装虚拟机,这其中涉及到一些细节操作,需要对虚拟机工作模式加以理解. 本文在学习hadoop分布式环境搭建时写作. 1.虚拟交换机 ...

  8. [心平气和读经典]The TCP/IP Guide(001)

    The TCP/IP Guide[Page 40,41] Introduction To the TCP/IP Guide | TCP/IP指南概述 As I sit here writing thi ...

  9. MySQL数据库-错误1166 - Incorrect column name 'xxx' 的解决方法

    在用Navicat for MySQL给MySQL数据库修改表的字段时报如下的错误: 解决方法:检查字段里面是不是有空格,去掉就可以了.

  10. CentOS VNC

    CentOS Linux:1.需要安装的包:tigervnc,tigervnc-server 2.配置显示分辨率.桌面和用户:编辑 /etc/sysconfig/vncservers参考注释掉的最后两 ...