考虑到每次除法,然后加法,差距会变小,于是维护加法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;
}

最新文章

  1. lisp中的cons
  2. 各种 starter poms (启动器)
  3. linux 问答
  4. dbvisualizer中文乱码
  5. java getEnv不区分大小写 getProperty区分大小写
  6. PHP定义数组常量
  7. LDA Gibbs Sampling
  8. oracle 如何重置用户密码
  9. Flex 动画效果
  10. jquery动态改变背景颜色插件
  11. Android 6.0 以后webview不加载图片的问题
  12. Autofac 依赖注入框架 使用
  13. Java并发编程之同步
  14. Socket网络编程基本介绍
  15. 转: wireshark的使用说明
  16. Sword STL之仿函数概念介绍
  17. codeforces水题100道 第十七题 Codeforces Beta Round #25 (Div. 2 Only) A. IQ test (brute force)
  18. MySQL数据库函数
  19. 深入理解java内存模型
  20. 论文 ClickP4: Towards Modular Programming of P4 小结

热门文章

  1. Centos 7 最小化部署svn版本控制(http协议)
  2. Jconsole或者VisualVM监控远程主机(阿里云,jdk11或者8)
  3. Leetcode 题目整理-6 Swap Nodes in Pairs &amp; Remove Duplicates from Sorted Array
  4. List容器排序方法的使用
  5. 【存储类、链接、存储管理】分配内存:malloc()、free()
  6. SASS用法入门
  7. python 内置模块之os、sys、shutil
  8. 林大妈的JavaScript进阶知识(二):JS异步行为
  9. 在家想自学Java,有C语言底子,请问哪本书适合?
  10. JUC中的锁