Solution -「LOJ #6029」「雅礼集训 2017」市场
Link.
维护序列 ,支持 次如下操作:
-
区间加法;
-
区间下取整除法;
-
区间求最小值;
-
区间求和。
,值域大约是 。
可以推测是势能线段树。对于线段树上的区间 ,想要将它 ,维护 以及 ,当 时直接打区间加法标记,否则递归处理。其他操作正常在线段树上进行,若不考虑各变量间的数量级关系,可证复杂度为 。
证明
设线段树上区间 有势能 ( 定义如上),总势能 ,则:- 初始状态,,;
- 区间加法,势能有变动的区间个数为 ,,故 ;
- 区间除法,设操作对象为区间 ,首先其有基础复杂度开销 ,也有可能带来至多 的势能增加。考虑树上一个被它完全覆盖的区间 。若在这个区间需要向下递归,则必然有 ,所以 ,其中 即递归入完全覆盖区间的次数。那么本次操作的复杂度为 。
综上,总复杂度为 ,即 ,当然第一项可以忽略。
/*~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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2020-08-23 Solution -「LOCAL」Burning Flowers