题意

链接

Sol

势能分析。

除法是不能打标记的,所以只能暴力递归。这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减。

这样复杂度是\((n + mlogn) logV\)的。

简单的证明一下:如果没有加的话,每个节点会被除至多log次, 总会除4nlogn次,每次区间加会恢复log个点的势能函数,这样总递归次数就是\(nlog^2n\)。

下传标记的时候别忘了把min和max都更新一下

#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define ull unsigned long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 1;
const double eps = 1e-9, pi = acos(-1);
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, Q, a[MAXN];
LL mx[MAXN], mn[MAXN], add[MAXN], sum[MAXN], ll[MAXN], rr[MAXN];
#define ls k << 1
#define rs k << 1 | 1
void update(int k) {
mx[k] = max(mx[ls], mx[rs]);
mn[k] = min(mn[ls], mn[rs]);
sum[k] = sum[ls] + sum[rs];
}
void ps(int k, int v) {
sum[k] += (rr[k] - ll[k] + 1) * v;
mn[k] += v; mx[k] += v;
add[k] += v;
}
void pushdown(int k) {
if(!add[k]) return ;
ps(ls, add[k]); ps(rs, add[k]);
add[k] = 0;
}
void Build(int k, int l, int r) {
ll[k] = l; rr[k] = r;
if(l == r) {sum[k] = mx[k] = mn[k] = a[l]; return ;}
int mid = l + r >> 1;
Build(ls, l, mid); Build(rs, mid + 1, r);
update(k);
}
void Add(int k, int l, int r, int ql, int qr, LL v) {
if(ql <= l && r <= qr) {ps(k, v); return ;}
int mid = l + r >> 1;
pushdown(k);
if(ql <= mid) Add(ls, l, mid, ql, qr, v);
if(qr > mid) Add(rs, mid + 1, r, ql, qr, v);
update(k);
}
LL get(LL x, int d) {
return (x >= 0 ? x / d : (x - d + 1) / d);
}
void Div(int k, int l, int r, int ql, int qr, LL v) {
if(ql <= l && r <= qr && (mx[k] - get(mx[k], v) == mn[k] - get(mn[k], v))) {
ps(k, get(mx[k], v) - mx[k]);
return ;
}
pushdown(k);
int mid = l + r >> 1;
if(ql <= mid) Div(ls, l, mid, ql, qr, v);
if(qr > mid) Div(rs, mid + 1, r, ql, qr, v);
update(k);
}
LL Min(int k, int l, int r, int ql, LL qr) {
if(ql <= l && r <= qr) return mn[k];
int mid = l + r >> 1;
pushdown(k);
if(ql > mid) return Min(rs, mid + 1, r, ql, qr);
else if(qr <= mid) return Min(ls, l, mid, ql, qr);
else return min(Min(ls, l, mid, ql, qr), Min(rs, mid + 1, r, ql, qr));
}
LL Sum(int k, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return sum[k];
int mid = l + r >> 1;
pushdown(k);
if(ql > mid) return Sum(rs, mid + 1, r, ql, qr);
else if(qr <= mid) return Sum(ls, l, mid, ql, qr);
else return Sum(ls, l, mid, ql, qr) + Sum(rs, mid + 1, r, ql, qr);
}
signed main() {
N = read(); Q = read();
for(int i = 1; i <= N; i++) a[i] = read();
Build(1, 1, N);
while(Q--) {
int opt = read(), l = read() + 1, r = read() + 1;
if(opt == 1) {
int c = read();
Add(1, 1, N, l, r, c);
} else if(opt == 2) {
int d = read();
Div(1, 1, N, l, r, d);
} else if(opt == 3) {
cout << Min(1, 1, N, l, r) << '\n';
} else {
cout << Sum(1, 1, N, l, r) << '\n';
}
}
return 0;
}

loj#6029. 「雅礼集训 2017 Day1」市场(线段树)的更多相关文章

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

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

  2. #6029. 「雅礼集训 2017 Day1」市场 [线段树]

    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可 #include <cstdio> #include <cmath> #define int long l ...

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

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

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

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

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

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

  6. loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移

    $ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...

  7. [LOJ 6031]「雅礼集训 2017 Day1」字符串

    [LOJ 6031] 「雅礼集训 2017 Day1」字符串 题意 给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询 ...

  8. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

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

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

随机推荐

  1. JAVA对象 向上转型upcasting,向下转型downcasting

    1:向上转型 向上转型,就是java多态中的父类引用指向子类对象.但要注意的是 父类引用不可以访问子类新增加的成员(属性和方法) 代码举例: /** * 定义一个父类 */ public class ...

  2. phtoshop cs6 下载安装及破解方法(另附Photoshop CC 2018破解版图文教程)

    前言: 前端虽然用PS不多,但有时需要用PS切图:UI给你PSD图,需要取色,查看字体颜色大小:测量元素宽高等 但有时想找一个“麻雀虽小,五脏俱全”又是破解版的PS,也不是那么容易的 注:ps完整版不 ...

  3. [Swift]创建CoreData的两种方式

    一.CoreData介绍 CoreData主要分为两部分: 上层是模型层,模型层有NSManagedObjectContext上下文管理着, 底层则是由SQLite实现的持久化部分,通过NSPersi ...

  4. python Event_loop(事件循环)

    由于GIL全局解释器锁的存在,意味着在任何一个时刻,只有一个线程处于执行状态. (1)执行栈: 因为python是单线程的,同一时间只能执行一个方法,所以当一系列的方法被依次调用的时候,python会 ...

  5. Spring整合MyBatis 你get了吗?

    Spring整合MyBatis 1.整体架构dao,entity,service,servlet,xml 2..引入依赖 <dependencies> <dependency> ...

  6. Xamarin.Android 解决打开软键盘导致底部菜单上移问题

    在界面布局中有EditText控件,该控件一旦获取焦点则打开软键盘,如果布局中有底部菜单,那么底部菜单可能会被软键盘顶在其上面,看如下效果: 解决方法:在活动绑定界面之前写上下段代码即可 Window ...

  7. ASP.NET Core微服务+Tabler前端框架搭建个人博客1--开始前想说的话

    写在前面 本人为在读研究生,特别喜欢.NET,觉得.NET的编程方式.语法都特别友好,学习.NET Core已经差不多有一年半了,从一开始不知道如何入门到现在终于可以编写一些小的应用程序,想一想还是非 ...

  8. ExternalException (0x80004005): 无法执行程序

    今天更新系统上传到阿里云服务器,报错如下: “/”应用程序中的服务器错误. 组策略阻止了这个程序.要获取详细信息,请与系统管理员联系. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆 ...

  9. ASP .NET CORE 根据环境变量支持多个 appsettings.json

    0.背景 在开发项目的过程当中,生产环境与调试环境的配置肯定是不一样的.拿个最简单的例子来说,比如连接字符串这种东西,调试环境肯定是不能连接生产数据库的.在之前的话,这种情况只能说是你 COPY 两个 ...

  10. [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.不认识到犯错,然后得到 ...