传送门:https://loj.ac/problem/6029

【题解】

考虑如果有一些近似连续的段

比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2

又:区间增加很容易造成这种段,所以我们猜测可以暴力维护

用一棵线段树即可。(好像真的能暴力维护啊 我不知道怎么证明复杂度)

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 4e5 + ;
const int mod = 1e9+; # define RG register
# define ST static int n, a[M];
struct SMT {
ll mx[M], mi[M], s[M], tag[M];
# define ls (x<<)
# define rs (x<<|)
inline void up(int x) {
s[x] = s[ls] + s[rs];
mx[x] = max(mx[ls], mx[rs]);
mi[x] = min(mi[ls], mi[rs]);
}
inline void pushtag(int x, ll tg, int len) {
mx[x] += tg;
mi[x] += tg;
s[x] += tg*len;
tag[x] += tg;
}
inline void down(int x, int l, int r) {
if(tag[x] == ) return ;
int mid = l+r>>;
pushtag(ls, tag[x], mid-l+);
pushtag(rs, tag[x], r-mid);
tag[x] = ;
}
inline void build(int x, int l, int r) {
tag[x] = ;
if(l == r) {
mx[x] = mi[x] = s[x] = a[l];
return ;
}
int mid = l+r>>;
build(ls, l, mid);
build(rs, mid+, r);
up(x);
}
inline void edt(int x, int l, int r, int L, int R, int c) {
if(L <= l && r <= R) {
pushtag(x, c, r-l+);
return ;
}
down(x, l, r);
int mid = l+r>>;
if(L <= mid) edt(ls, l, mid, L, R, c);
if(R > mid) edt(rs, mid+, r, L, R, c);
up(x);
}
inline void div(int x, int l, int r, int L, int R, int d) {
if(L <= l && r <= R) {
ll A, B;
if(mi[x] < ) A = (mi[x] - d + ) / d;
else A = mi[x] / d;
if(mx[x] < ) B = (mx[x] - d + ) / d;
else B = mx[x] / d;
if(mi[x] - A == mx[x] - B) {
pushtag(x, A - mi[x], r-l+);
return ;
}
}
down(x, l, r);
int mid = l+r>>;
if(L <= mid) div(ls, l, mid, L, R, d);
if(R > mid) div(rs, mid+, r, L, R, d);
up(x);
}
inline ll sum(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return s[x];
down(x, l, r);
int mid = l+r>>;
ll ret = ;
if(L <= mid) ret += sum(ls, l, mid, L, R);
if(R > mid) ret += sum(rs, mid+, r, L, R);
return ret;
}
inline ll gmin(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return mi[x];
down(x, l, r);
int mid = l+r>>;
ll ret = 1e18;
if(L <= mid) ret = min(ret, gmin(ls, l, mid, L, R));
if(R > mid) ret = min(ret, gmin(rs, mid+, r, L, R));
return ret;
}
}T; int main() {
int Q, opt, l, r, x;
cin >> n >> Q;
for (int i=; i<=n; ++i) scanf("%d", a+i);
T.build(, , n);
while(Q--) {
scanf("%d%d%d", &opt, &l, &r); ++l, ++r;
if(opt == ) {
scanf("%d", &x);
T.edt(, , n, l, r, x);
} else if(opt == ) {
scanf("%d", &x);
T.div(, , n, l, r, x);
} else if(opt == ) printf("%lld\n", T.gmin(, , n, l, r));
else printf("%lld\n", T.sum(, , n, l, r));
}
return ;
}

最新文章

  1. PHP学习-链接数据库
  2. 【Delphi7】 解决“程序第一次可以正常编译,但再次编译的时候会报错,必须重新打开Delphi”的问题
  3. Nginx下WordPress的Rewrite
  4. C#进阶系列——WebApi身份认证解决方案:Basic基础认证 (转)
  5. Analyzing The Papers Behind Facebook&#39;s Computer Vision Approach
  6. busybox filesystem matrix-gui-2.0 undefined function json_encode()
  7. RMAN常用备份恢复命令汇总
  8. Tomcat学习笔记 - 错误日志 - Tomcat安装版安装后第二次启动后闪退(转)-- javac不是内部或外部命令 -- 配置java环境教程
  9. Linux 内核参数 arp_ignore &amp; arp_announce 详解
  10. ES6 中 Promise
  11. Python_装饰器进阶_32
  12. formelf.exe的用法
  13. Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D) - 记忆化搜索
  14. js 处理Json 时间带T 时间格式
  15. Python sys.argv[] 的用法
  16. easyui datagrid加载数据的三种方式
  17. 并发基础(二) Thread类的API总结
  18. linux的零碎知识
  19. 课堂讨论—Alpha版总结会议
  20. opencv-从图像旋转学习Mat数据訪问

热门文章

  1. 高德API+.NET解决租房问题(JS相关)
  2. HI2115软件开发板V150版本AT+NSOST指令
  3. zabbix 一些问题随记
  4. 使用HashOperations操作redis
  5. Java 实现一个带提醒的定时器
  6. c# 生成dll
  7. 在C的头文件中定义的结构体,如何在cpp文件中引用
  8. 【其他】Windows 系统安装IIS 打开页面出现空白解决方案
  9. windows curl 命令
  10. git查看和操作commit命令