\(\mathcal{Description}\)

  Link.

  维护序列 \(\lang a_n\rang\),支持 \(q\) 次如下操作:

  1. 区间加法;

  2. 区间下取整除法;

  3. 区间求最小值;

  4. 区间求和。

    \(n,q\le10^5\),值域大约是 \(V=2\times10^9\)。

\(\mathcal{Solution}\)

  可以推测是势能线段树。对于线段树上的区间 \([l,r]\),想要将它 \(\div d\),维护 \(u=\min_{i=l}^r\{a_i\}\) 以及 \(v=\max_{i=l}^r\{a_i\}\),当 \(\lfloor\frac{u}{d}\rfloor-u=\lfloor\frac{v}{d}\rfloor-v\) 时直接打区间加法标记,否则递归处理。其他操作正常在线段树上进行,若不考虑各变量间的数量级关系,可证复杂度为 \(\mathcal O((n+q\log n)\log V)\)。

证明

  设线段树上区间 $[l,r]$ 有势能 $\Phi[l,r]=\log(v-u)$($v,u$ 定义如上),总势能 $\Phi=\sum\Phi[l,r]$,则:

  • 初始状态,\(\Phi[l,r]\le\mathcal O(\log V)\),\(\Phi\le\mathcal O(n\log V)\);
  • 区间加法,势能有变动的区间个数为 \(\mathcal O(\log n)\),\(\Delta\Phi[l,r]\le\mathcal O(\log V)\),故 \(\Delta\Phi=\sum\Delta\Phi[l,r]\le\mathcal O(\log n\log V)\);
  • 区间除法,设操作对象为区间 \([s,e]\),首先其有基础复杂度开销 \(\mathcal O(\log n)\),也有可能带来至多 \(\mathcal O(\log n\log V)\) 的势能增加。考虑树上一个被它完全覆盖的区间 \([l,r]\)。若在这个区间需要向下递归,则必然有 \(\Delta\Phi[l,r]\le-1\),所以 \(\Delta\Phi\propto x\),其中 \(x\) 即递归入完全覆盖区间的次数。那么本次操作的复杂度为 \(\mathcal O(\log n+x)\)。

  综上,总复杂度为 \(\mathcal O(q\log n)+\sum x\),即 \(\mathcal O(q\log n+n\log V+q\log n\log V)\),当然第一项可以忽略。 \(\square\)

\(\mathcal{Code}\)

/*~Rainybunny~*/

#include <cmath>
#include <cstdio> #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i ) typedef long long LL;
#define int LL inline int rint() {
int x = 0, f = 1, s = getchar();
for ( ; s < '0' || '9' < s; s = getchar() ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar() ) x = x * 10 + ( s ^ '0' );
return x * f;
} template<typename Tp>
inline void wint( Tp x ) {
if ( x < 0 ) putchar( '-' ), x = -x;
if ( 9 < x ) wint( x / 10 );
putchar( x % 10 ^ '0' );
} inline int imin( const int a, const int b ) { return a < b ? a : b; }
inline int imax( const int a, const int b ) { return a < b ? b : a; } const int MAXN = 1e5, IINF = 1ll << 60;
int n, q; struct SegmentTree {
int len[MAXN << 2], mx[MAXN << 2], mn[MAXN << 2], adt[MAXN << 2];
LL sum[MAXN << 2]; inline void pushup( const int u ) {
mx[u] = imax( mx[u << 1], mx[u << 1 | 1] );
mn[u] = imin( mn[u << 1], mn[u << 1 | 1] );
sum[u] = sum[u << 1] + sum[u << 1 | 1];
} inline void pushad( const int u, const int v ) {
adt[u] += v, mn[u] += v, mx[u] += v, sum[u] += 1ll * v * len[u];
} inline void pushdn( const int u ) {
if ( adt[u] ) {
pushad( u << 1, adt[u] ), pushad( u << 1 | 1, adt[u] );
adt[u] = 0;
}
} inline void build( const int u, const int l, const int r ) {
len[u] = r - l + 1;
if ( l == r ) return void( mx[u] = mn[u] = sum[u] = rint() );
int mid = l + r >> 1;
build( u << 1, l, mid ), build( u << 1 | 1, mid + 1, r );
pushup( u );
} inline void add( const int u, const int l, const int r,
const int al, const int ar, const int v ) {
if ( al <= l && r <= ar ) return pushad( u, v );
int mid = l + r >> 1; pushdn( u );
if ( al <= mid ) add( u << 1, l, mid, al, ar, v );
if ( mid < ar ) add( u << 1 | 1, mid + 1, r, al, ar, v );
pushup( u );
} inline void div( const int u, const int l, const int r,
const int dl, const int dr, const int v ) {
// if ( v == 1 ) return ;
if ( dl <= l && r <= dr && mx[u] - floor( 1. * mx[u] / v )
== mn[u] - floor( 1. * mn[u] / v ) ) {
return pushad( u, floor( 1. * mx[u] / v ) - mx[u] );
}
int mid = l + r >> 1; pushdn( u );
if ( dl <= mid ) div( u << 1, l, mid, dl, dr, v );
if ( mid < dr ) div( u << 1 | 1, mid + 1, r, dl, dr, v );
pushup( u );
} inline int qmin( const int u, const int l, const int r,
const int ql, const int qr ) {
if ( ql <= l && r <= qr ) return mn[u];
int mid = l + r >> 1, ret = IINF; pushdn( u );
if ( ql <= mid ) ret = imin( ret, qmin( u << 1, l, mid, ql, qr ) );
if ( mid < qr )
ret = imin( ret, qmin( u << 1 | 1, mid + 1, r, ql, qr ) );
return ret;
} inline LL qsum( const int u, const int l, const int r,
const int ql, const int qr ) {
if ( ql <= l && r <= qr ) return sum[u];
int mid = l + r >> 1; LL ret = 0; pushdn( u );
if ( ql <= mid ) ret += qsum( u << 1, l, mid, ql, qr );
if ( mid < qr ) ret += qsum( u << 1 | 1, mid + 1, r, ql, qr );
return ret;
}
} sgt; signed main() {
n = rint(), q = rint();
sgt.build( 1, 0, n - 1 );
for ( int op, l, r; q--; ) {
op = rint(), l = rint(), r = rint();
if ( op == 1 ) sgt.add( 1, 0, n - 1, l, r, rint() );
else if ( op == 2 ) sgt.div( 1, 0, n - 1, l, r, rint() );
else if ( op == 3 ) wint( sgt.qmin( 1, 0, n - 1, l, r ) ), puts( "" );
else wint( sgt.qsum( 1, 0, n - 1, l, r ) ), puts( "" );
}
return 0;
}

Solution -「LOJ #6029」「雅礼集训 2017」市场的更多相关文章

  1. [雅礼集训 2017 Day1]市场

    link 试题分析 可以容易发现此题维护的是一个数据结构,支持区间加,区间除,区间查询最大值.其实就是在$\log$级复杂度内维护除法操作. 我们发现当除数很大或者此串序列大小差不多时,我们令$a_i ...

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

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

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

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

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

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

  5. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 …… 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  6. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  7. 「雅礼集训 2017 Day7」事情的相似度

    「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...

  8. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  9. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

随机推荐

  1. CentOS7防火墙firewalld 和 CentOS6防火墙iptables的一些配置命令

    CentOS7 防火墙 一.防火墙的开启.关闭.禁用.查看状态命令 (1)启动防火墙:systemctl start firewalld (2)关闭防火墙:systemctl stop firewal ...

  2. Centos6.8安装并配置VNC

    一般服务器都会在IDC或云端,为了可以看到服务器的图形化界面,需要安装配置VNC,本例为Centos6.8上安装配置VNC. [root@hostname ~]#yum install -y tige ...

  3. Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  4. 【Java常用类】LocalDate、LocalTime、LocalDateTime

    LocalDate.LocalTime.LocalDateTime 说明 JDK 1.0中包含了 一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被 ...

  5. MRCTF2020 你传你🐎呢

    MRCTF2020 你传你 .htaccess mime检测 1.先尝试上传了一个文件,发现.jpg后缀的可以上传成功,但是用蚁剑连接时返回空数据 2.重新先上传一个.htaccess文件,让需要被上 ...

  6. [MRCTF2020]Ezaudit

    [MRCTF2020]Ezaudit 知识点 1.源码泄露 2.伪随机数 3.sql注入? 题解 打开题目是个漂亮的前端,扫一下发现www.zip文件泄露,下载审计 <?php header(' ...

  7. 【记录一个问题】铁威马NAS存储中的python3,安装后找不到xml这个包

    如题 因为找不到xml,所以无法安装setuptools 因为无法安装setuptools,所以无法安装pip3 现在准备重新下载python3的源码自己编译. 铁威马的系统中还缺少libm这个库,导 ...

  8. 羽夏看Win系统内核——进程线程篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  9. 学习AJAX必知必会(3)~自动重启工具nodemon、缓存问题、请求超时和网络异常、取消重复请求

    1.nodemon 自动重启工具(自动重启基于nodejs开发的服务端应用) ■ nodemon 是一个工具,通过在检测到目录中的文件更改时自动重新启动node应用程序来帮助开发node.js. // ...

  10. 【webpack4.0】---dev.config.js基本配置(六)

    一.开发环境配置准备 1.创建dev.config.js文件 用来配置开发环境的代码 2.安装webpack-merge cnpm install webpack-merge -D 用来合并webpa ...