#6029. 「雅礼集训 2017 Day1」市场 [线段树]
考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可
#include <cstdio>
#include <cmath>
#define int long long
int read() {
int x = 0;
bool f = 0;
char c = getchar();
while (c < 48) f ^= (c == '-'), c = getchar();
while (c > 47) x = x * 10 + (c - 48), c = getchar();
return f ? -x : x;
}
int n, m;
const int maxn = 1e5 + 51;
int a[maxn];
int mn[maxn << 2], mx[maxn << 2];
int del[maxn << 2], sum[maxn << 2];
int min(int x, int y) { return x < y ? x : y; }
int max(int x, int y) { return x > y ? x : y; }
void pushup(int rt) {
mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);
mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt) {
if (l == r) {
sum[rt] = mn[rt] = mx[rt] = a[l];
return;
}
int mid = l + r >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
void pushtag(int l, int r, int rt, int x) {
del[rt] += x, mn[rt] += x, mx[rt] += x;
sum[rt] += x * (r - l + 1);
}
void pushd(int l, int r, int rt) {
if (!del[rt]) return;
int mid = l + r >> 1;
pushtag(l, mid, rt << 1, del[rt]);
pushtag(mid + 1, r, rt << 1 | 1, del[rt]);
del[rt] = 0;
}
void modify(int a, int b, int l, int r, int rt, int v) {
if (a <= l && r <= b) {
pushtag(l, r, rt, v);
return;
}
pushd(l, r, rt);
int mid = l + r >> 1;
if (a <= mid) modify(a, b, l, mid, rt << 1, v);
if (b > mid) modify(a, b, mid + 1, r, rt << 1 | 1, v);
pushup(rt);
}
void div(int a, int b, int l, int r, int rt, int v) {
if (a <= l && r <= b) {
int tx = floor((double)mx[rt] / v);
int ty = floor((double)mn[rt] / v);
if (tx - mx[rt] == ty - mn[rt]) {
pushtag(l, r, rt, tx - mx[rt]);
return;
}
pushd(l, r, rt);
int mid = l + r >> 1;
div(a, b, l, mid, rt << 1, v), div(a, b, mid + 1, r, rt << 1 | 1, v);
pushup(rt);
return;
}
pushd(l, r, rt);
int mid = l + r >> 1;
if (a <= mid) div(a, b, l, mid, rt << 1, v);
if (b > mid) div(a, b, mid + 1, r, rt << 1 | 1, v);
pushup(rt);
}
int qry(int a, int b, int l, int r, int rt) {
if (a <= l && r <= b) return sum[rt];
pushd(l, r, rt);
int mid = l + r >> 1;
int ans = 0;
if (a <= mid) ans = qry(a, b, l, mid, rt << 1);
if (b > mid) ans += qry(a, b, mid + 1, r, rt << 1 | 1);
return ans;
}
int qrymin(int a, int b, int l, int r, int rt) {
if (a <= l && r <= b) return mn[rt];
pushd(l, r, rt);
int mid = l + r >> 1;
int ans = 1e18;
if (a <= mid) ans = min(ans, qrymin(a, b, l, mid, rt << 1));
if (b > mid) ans = min(ans, qrymin(a, b, mid + 1, r, rt << 1 | 1));
return ans;
}
signed main() {
n = read(), m = read();
for (int i = 1; i <= n; i++) a[i] = read();
build(1, n, 1);
while (m--) {
int op;
op = read();
if (op == 1) {
int l, r, x;
l = read(), r = read(), x = read();
++l, ++r;
modify(l, r, 1, n, 1, x);
}
if (op == 2) {
int l, r, x;
l = read(), r = read(), x = read();
++l, ++r;
div(l, r, 1, n, 1, x);
}
if (op == 3) {
int l, r;
l = read(), r = read();
++l, ++r;
printf("%lld\n", qrymin(l, r, 1, n, 1));
}
if (op == 4) {
int l, r;
l = read(), r = read();
++l, ++r;
printf("%lld\n", qry(l, r, 1, n, 1));
}
}
return 0;
}
#6029. 「雅礼集训 2017 Day1」市场 [线段树]的更多相关文章
- loj#6029. 「雅礼集训 2017 Day1」市场(线段树)
题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...
- LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法
题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...
- 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...
- 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...
- [LOJ 6029]「雅礼集训 2017 Day1」市场
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...
- loj6029 「雅礼集训 2017 Day1」市场
传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...
- 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题
题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...
- 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)
点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...
- 【loj6029】「雅礼集训 2017 Day1」市场
题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...
随机推荐
- mysql--->mysql查看数据库操作记录
mysql查看数据库操作记录 MySQL的查询日志记录了所有MySQL数据库请求的信息.无论这些请求是否得到了正确的执行.默认文件名为hostname.log.默认情况下MySQL查询日志是关闭的.生 ...
- Java异常 | Error:java: Compilation failed: internal java compiler error
背景 今天网上下载了一个项目,编辑运行报如下异常: Error:java: Compilation failed: internal java compiler error 经过往经验,读项目的编译环 ...
- 暑假第四周总结(HDFS编程实践,安装HBASE)
本周根据书上以及教程的提示,对HDFS进行了编程实践,将教程所给的代码(判断文件是否存在,创建文件,读取文件)进行了应用,根据视频的讲解,对一些简单的语句有了一定的了解,但还是比较生疏.另外还根据提示 ...
- Java的变量与常量
常量: 在程序运行期间,固定不变得量. 常量的分类: 字符串常量:凡是用双引号引起来的部分,叫做字符串常量.例如:“abc”.“Hello”.“123”. 整数常量:直接写上的数字,没有小数点.例如: ...
- javaIO编码详解
原创 输出流 有哪些构造方法可以在参数上设置编码格式 PrintStream(File file, String csn) PrintStream(String fileName, String cs ...
- [C/C++]_[Unicode转Utf8,Ansi转Unicode,Ansi文件转Utf8文件]
http://blog.csdn.net/infoworld/article/details/15337665 场景: 1.也就只有windows需要那么麻烦,还搞一个ANSI编码.学学mac os ...
- VC获取cookies的几种方法
方法一: CInternetSession::GetCookie This member function implements the behavior of the Win32 function ...
- 【WPF学习】第四十章 画刷
画刷填充区域,不管是元素的背景色.前景色以及边框,还是形状的内部填充和笔画(Stroke).最简单的画刷类型是SolidColorBrush,这种画刷填充一种固定.连续的颜色.在XAML中设置形状的S ...
- POJ_1376_bfs
题目描述: 给定一个黑白格子的图,黑格子是障碍物,一个线段交点的起点,一个线段交点的终点和初始方向,机器人从起点开始,只能沿着线段,走到终点,期间不能沿着障碍物边缘和墙边缘. 一次操作可以向当前方向走 ...
- 关于Icon,Image,ImageIcon的简单的对比参考
Icon: Icon位于javax.swing包中,它是一个接口 public interface Icon,介绍为:一个小的固定大小的图片,通常用于装饰组件 有三个方法: int getIconHe ...