考虑到每次除法,然后加法,差距会变小,于是维护加法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」市场 [线段树]的更多相关文章

  1. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  2. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  3. 【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之 ...

  4. 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)

    老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...

  5. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  6. loj6029 「雅礼集训 2017 Day1」市场

    传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区 ...

  7. 【loj6029】「雅礼集训 2017 Day1」市场&&【uoj#228】基础数据结构练习题

    题解: 这两道题加上区间取min max应该算线段树几道比较不寻常的题目 其实也是挺好理解的 对于区间/d 显然在log次后就会等于0 而我们注意到如果区间中数都相等那么就可以一起除 也就是说每个区间 ...

  8. 【LOJ6029】「雅礼集训 2017 Day1」市场(线段树裸题)

    点此看题面 大致题意: 维护序列,支持区间加法,区间除法(向下取整),区间求\(min\)和区间求和. 线段树维护区间除法 区间加法.区间求\(min\)和区间求和都是线段树基本操作,因此略过不提. ...

  9. 【loj6029】「雅礼集训 2017 Day1」市场

    题目 题意:四种操作,区间加法.区间除法(下取整).区间求最小值.区间求和. 第1.3.4个操作都是摆设,关键在于如何做区间除法. 很明显不能直接把区间的和做除法后向下取整,因为区间和可能会多凑出一个 ...

随机推荐

  1. mysql安装教程linux

    https://www.cnblogs.com/YangshengQuan/p/8431520.html 设置sql远程访问

  2. 在 Ubuntu 上安装 K8S教程

    在 Ubuntu 上安装 K8S教程 1,更新系统源 如果系统本身自带得镜像地址,服务器在国外,下载速度会很慢,可以打开 /etc/apt/sources.lis 替换为国内得镜像源. apt upg ...

  3. c++中多文件的组织

    参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第八章 根据书中例子学习使用类的多文件项目. 首先要将类CBox定义成一个连贯的整体,在CBox.H文件中写入相关的类定义, ...

  4. vuex源码简析

    前言 基于 vuex 3.12 按如下流程进行分析: Vue.use(Vuex); const store = new Vuex.Store({ actions, getters, state, mu ...

  5. TS 原理详细解读(5)语法2-语法解析

    在上一节介绍了语法树的结构,本节则介绍如何解析标记组成语法树. 对应的源码位于 src/compiler/parser.ts. 入口函数 要解析一份源码,输入当然是源码内容(字符串),同时还提供路径( ...

  6. Day of Week

    题目1043:Day of Week 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1544 解决:609 题目描述: We now use the Gregorian style of ...

  7. java架构之路-(netty专题)初步认识BIO、NIO、AIO

    本次我们主要来说一下我们的IO阻塞模型,只是不多,但是一定要理解,对于后面理解netty很重要的 IO模型精讲  IO模型就是说用什么样的通道进行数据的发送和接收,Java共支持3种网络编程IO模式: ...

  8. shell命令之一天一见:grep

    一. 简介 grep (缩写来自Globally search a Regular Expression and Print)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来 ...

  9. Codeforces_739_B

    http://codeforces.com/problemset/problem/739/B dfs,记录距离前缀和,每次找到离最近的不符合的点. #include<iostream> # ...

  10. Jmeter之设置动态关联

    前言 在Jmeter中,如何进行接口关联(上一个接口的返回参数作为下一个接口的入参使用)测试呢?下面我们一起来学习吧! 需求:需要利用商品信息接口的返回结果skuName值作为下一个登录接口参数Use ...