势能线段树(均摊分析)

势能线段树

线段树能够通过打懒标记实现区间修改的条件有两个:

  1. 能够快速处理懒标记对区间询问结果的影响
  2. 能够快速实现懒标记的合并

但有的区间修改不满足上面两个条件(如区间整除/开方/取模等)。
但某些修改存在一些奇妙的性质,使得序列每个元素被修改的次数有一个上限

所以可以在线段树每个节点上记录一个值,表示对应区间内是否每个元素都达到修改次数上限。区间修改时暴力递归到叶子节点,如果途中遇到一个节点,这个节点的对应区间内每个元素都达到修改次数上限则在这个节点returnreturnreturn掉。

可以证明复杂度为 O((n+mlog⁡n)×lim)O((n+m\log n)\times lim)O((n+mlogn)×lim),其中nnn为序列长度,mmm为询问次数,limlimlim为修改次数上限。

LOJ6029——线段树区间除法

对于每个区间维护区间内的 最大值MaxMaxMax 和 最小值MinMinMin,对于整除操作,如果有Max−⌊Maxd⌋=Min−⌊Mind⌋Max-\lfloor\frac{Max}{d}\rfloor = Min − \lfloor\frac{Min}{d}\rfloorMaxdMax=MindMin,就转化为区间减。否则直接向下递归。

考虑何时满足Max−⌊Maxd⌋=Min−⌊Mind⌋Max-\lfloor\frac{Max}{d}\rfloor = Min − \lfloor\frac{Min}{d}\rfloorMaxdMax=MindMin
Max=k1d+c1,Min=k2d+c2(c1,c2∈[0,d−1],d≥2)Max=k_1d+c_1,Min=k_2d+c_2(c_1,c_2\in[0,d-1],d\geq 2)Max=k1d+c1,Min=k2d+c2(c1,c2[0,d1],d2)
Max−⌊Maxd⌋=Min−⌊Mind⌋Max-\lfloor\frac{Max}{d}\rfloor=Min-\lfloor\frac{Min}{d}\rfloorMaxdMax=MindMin
Max−Min=⌊Maxd⌋−⌊Mind⌋Max-Min=\lfloor\frac{Max}{d}\rfloor-\lfloor\frac{Min}{d}\rfloorMaxMin=dMaxdMin
(k1−k2)d+c1−c2=k1−k2(k_1-k_2)d+c_1-c_2=k_1-k_2(k1k2)d+c1c2=k1k2
(k1−k2)(d−1)=c2−c1(k_1-k_2)(d-1)=c_2-c_1(k1k2)(d1)=c2c1
若k1=k2,则c2=c1,所以Max=Min若k_1=k_2,则c_2=c_1,所以Max=Mink1=k2,c2=c1,Max=Min
若k1>k2,则(k1−k2)(d−1)≥d−1,又因为c2−c1≤d−1,所以当且仅当Max=k1d,Min=(k1−1)d+d−1时成立若k_1>k_2,则(k_1-k_2)(d-1)\geq d-1,又因为c_2-c_1\leq d-1,所以当且仅当Max=k_1d,Min=(k_1-1)d+d-1时成立k1>k2,(k1k2)(d1)d1,c2c1d1,Max=k1d,Min=(k11)d+d1

所以一个区间最多暴力向下递归log⁡2(Max−Min)\log_2(Max-Min)log2(MaxMin)次。记势能函数ϕ(T)\phi(T)ϕ(T)为线段树TTT每一个节点log⁡(Max−Min)\log(Max−Min)log(MaxMin)的和,每一次修改操作会影响O(log⁡n)O(\log n)O(logn)个节点的Max−MinMax-MinMaxMin值,让ϕ(T)\phi(T)ϕ(T)增加log⁡nlog⁡A\log n\log AlognlogA,其中AAA为值域。因此总时间复杂度为O(nlog⁡A+mlog⁡nlog⁡A)O(n\log A+m\log n\log A)O(nlogA+mlognlogA)

UOJ228——线段树区间开根

同上,对于每个区间维护区间内的 最大值MaxMaxMax 和 最小值MinMinMin,对于开根操作,如果有Max−⌊Max⌋=Min−⌊Min⌋Max-\lfloor\sqrt{Max}\rfloor = Min − \lfloor\sqrt{Min}\rfloorMaxMax=MinMin,就转化为区间减。否则直接向下递归。

考虑何时满足Max−⌊Max⌋=Min−⌊Min⌋Max-\lfloor\sqrt{Max}\rfloor = Min − \lfloor\sqrt{Min}\rfloorMaxMax=MinMin
Max=k12+c1,Min=k22+c2(c1∈[0,2k1];c2∈[0,2k2];k1,k2≥1)Max=k_1^2+c_1,Min=k_2^2+c_2(c_1\in[0,2k_1];c_2\in[0,2k_2];k_1,k_2\geq 1)Max=k12+c1,Min=k22+c2(c1[0,2k1];c2[0,2k2];k1,k21)
Max−⌊Max⌋=Min−⌊Min⌋Max-\lfloor\sqrt{Max}\rfloor = Min − \lfloor\sqrt{Min}\rfloorMaxMax=MinMin
k12+c1−k1=k22+c2−k2k_1^2+c_1-k_1=k_2^2+c_2-k_2k12+c1k1=k22+c2k2
k12−k22−(k1−k2)=c2−c1k_1^2-k_2^2-(k_1-k_2)=c_2-c_1k12k22(k1k2)=c2c1
(k1+k2−1)(k1−k2)=c2−c1(k_1+k_2-1)(k_1-k_2)=c_2-c_1(k1+k21)(k1k2)=c2c1
若k1=k2,则c2=c1,所以Max=Min若k_1=k_2,则c_2=c_1,所以Max=Mink1=k2,c2=c1,Max=Min
若k1>k2,则(k1+k2−1)(k1−k2)≥k1+k2−1≥2k2,又因为c2−c1≤2k2,所以当且仅当Max=k12,Min=(k1−1)2+2(k1−1)=k12−1时成立若k_1>k_2,则(k_1+k_2-1)(k_1-k_2)\geq k_1+k_2-1\geq 2k_2,又因为c_2-c_1\leq 2k_2,所以当且仅当Max=k_1^2,Min=(k_1-1)^2+2(k_1-1)=k_1^2-1时成立k1>k2,(k1+k21)(k1k2)k1+k212k2,c2c12k2,Max=k12,Min=(k11)2+2(k11)=k121

开根后,区间极差由Max−MinMax-MinMaxMin变为Max−Min\sqrt{Max}-\sqrt{Min}MaxMin,又由Max−MinMax−Min=Max+Min>Max−Min\frac{Max-Min}{\sqrt{Max}-\sqrt{Min}}=\sqrt{Max}+\sqrt{Min}>\sqrt{Max}-\sqrt{Min}MaxMinMaxMin=Max+Min>MaxMinMax−Min>Max−Min\sqrt{Max-Min}>\sqrt{Max}-\sqrt{Min}MaxMin>MaxMin

所以一个区间最多暴力向下递归 log⁡log⁡(Max−Min)\log\log(Max−Min)loglog(MaxMin) 次,总时间复杂度为O(nlog⁡log⁡A+mlog⁡nlog⁡log⁡A)O(n\log\log A+m\log n\log\log A)O(nloglogA+mlognloglogA),其中AAA为值域。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf=1e9+7;
const int N=1e5+10;
ll mx[N<<2],mn[N<<2],sum[N<<2],tag[N<<2],a[N];
int n,q;
ll Sqr(ll x){return sqrt(x);
}
void build(int u,int l,int r){tag[u]=0;if(l==r){mx[u]=mn[u]=sum[u]=a[l];return;}int mid=(l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);mx[u]=max(mx[u<<1],mx[u<<1|1]);mn[u]=min(mn[u<<1],mn[u<<1|1]);sum[u]=sum[u<<1]+sum[u<<1|1];
}
void pushdown(int u,int l,int r){if(tag[u]!=0){int mid=(l+r)>>1;mx[u<<1]+=tag[u];mn[u<<1]+=tag[u];sum[u<<1]+=tag[u]*(mid-l+1);tag[u<<1]+=tag[u];mx[u<<1|1]+=tag[u];mn[u<<1|1]+=tag[u];sum[u<<1|1]+=tag[u]*(r-mid);tag[u<<1|1]+=tag[u];tag[u]=0;}
}
void add(int u,int l,int r,int a,int b,ll x){if(a<=l&&r<=b){mx[u]+=x;mn[u]+=x;sum[u]+=x*(r-l+1);tag[u]+=x;return;}pushdown(u,l,r);int mid=(l+r)>>1;if(a<=mid) add(u<<1,l,mid,a,b,x);if(b>mid) add(u<<1|1,mid+1,r,a,b,x);mx[u]=max(mx[u<<1],mx[u<<1|1]);mn[u]=min(mn[u<<1],mn[u<<1|1]);sum[u]=sum[u<<1]+sum[u<<1|1];
}
void sqr(int u,int l,int r,int a,int b){if(a<=l&&r<=b&&mx[u]-Sqr(mx[u])==mn[u]-Sqr(mn[u])){ll x=mx[u]-Sqr(mx[u]);mx[u]-=x;mn[u]-=x;sum[u]-=x*(r-l+1);tag[u]-=x;return;}pushdown(u,l,r);int mid=(l+r)>>1;if(a<=mid) sqr(u<<1,l,mid,a,b);if(b>mid) sqr(u<<1|1,mid+1,r,a,b);mx[u]=max(mx[u<<1],mx[u<<1|1]);mn[u]=min(mn[u<<1],mn[u<<1|1]);sum[u]=sum[u<<1]+sum[u<<1|1];
}
ll Sum(int u,int l,int r,int a,int b){if(a<=l&&r<=b) return sum[u];pushdown(u,l,r);int mid=(l+r)>>1;ll res=0;if(a<=mid) res=res+Sum(u<<1,l,mid,a,b);if(b>mid) res=res+Sum(u<<1|1,mid+1,r,a,b);return res;
}
int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);build(1,1,n);int opt,l,r;ll x;while(q--){scanf("%d%d%d",&opt,&l,&r);if(opt==1){scanf("%lld",&x);add(1,1,n,l,r,x);}else if(opt==2){sqr(1,1,n,l,r);}else if(opt==3){printf("%lld\n",Sum(1,1,n,l,r));}}return 0;
} 

CF438D——线段树区间取模

对于每个区间维护区间内的 最大值MaxMaxMax,对于整除操作,如果有Max<modMax<modMax<mod,就直接忽略。否则暴力向下递归。
可以证明,对于一个数xxx,最多取模log⁡x\log xlogx次就会令其变为1:

  • mod>x2mod>\frac{x}{2}mod>2x,那么x%mod=x−mod<x2x\%mod=x−mod<\frac{x}{2}x%mod=xmod<2x
  • mod=x2mod=\frac{x}{2}mod=2x,那么x%mod=0x\%mod=0x%mod=0
  • mod<x2mod<\frac{x}{2}mod<2x,那么x%mod<mod<x2x\%mod<mod<\frac{x}{2}x%mod<mod<2x

总时间复杂度为(nlog⁡A+mlog⁡nlog⁡A)(n\log A+m\log n\log A)(nlogA+mlognlogA),其中AAA为值域。

CF920F——线段树区间取约数个数

D(x)D(x)D(x)表示xxx的约数个数。
发现D(x)D(x)D(x)有以下性质:

  1. x≤2x\leq 2x2D(x)=xD(x)=xD(x)=x
  2. D(x)≤2xD(x)\leq 2\sqrt{x}D(x)2x

那么一个数xxx的修改次数上限为log⁡log⁡x\log\log xloglogx
套用上面的方法即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core 出得云端入得本地,微软让跨平台应用勇敢表达

地铁公交的上班路上、咖啡馆里等人的时候&#xff0c;这些碎片化时间都是现代人学习和充电的机会&#xff0c;根据第42次CNNIC中国互联网发展状况统计报告&#xff0c;截至2018年6月&#xff0c;网络文学用户规模已达4.06亿&#xff0c;占网民总体50.6%&#xff1b;手机网络文学…

【每日一题】7月3日精讲—毒瘤xor

【每日一题】7月3日精讲—毒瘤xor 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K Special Judge, 64bit IO Format: %lld文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 输入描述: 第一行一个整…

【DP】集合问题(2015特长生 T4/luogu 1466)

正题 luogu 1466 题目大意 给你1~n的一个集合&#xff0c;问你有多少种方案把该集合分成两个集合&#xff0c;且两集合的数字之和相等 解题思路 设fi,jf_{i,j}fi,j​为放好i个数且集合1的和比集合2的和大j的方案书 那么对于第i个放到两个集合中&#xff0c;分别从fi−1,j−…

P5212-SubString【LCT,SAM】

正题 题目链接:https://www.luogu.com.cn/problem/P5212 题目大意 开始一个字符串SSS&#xff0c;有nnn次操作 在SSS末尾加入一个字符串询问一个串在SSS中出现了多少次 强制在线 解题思路 强制在线的话&#xff0c;只有SAM\text{SAM}SAM能够支持动态插字符了&#xff0c;但…

了解改良圈算法

一.相关知识——Hamilton圈 什么是Hamilton圈&#xff1f; 哈密顿图&#xff08;哈密尔顿图&#xff09;&#xff08;英语&#xff1a;Hamiltonian path&#xff0c;或Traceable path&#xff09;是一个无向图&#xff0c;由天文学家哈密顿提出&#xff0c;由指定的起点前往指…

ASP.NET Core Middleware

中间件(Middleware)是ASP.NET Core中的一个重要特性。所谓中间件就是嵌入到应用管道中用于处理请求和响应的一段代码。ASP.NET Core Middleware可以分为两种类型&#xff1a;Conventional MiddlewareIMiddlewareConventional Middleware这种中间件没有实现特定的接口或者继承特…

NOIP复健计划——动态规划

树形DP [POI2011] DYN-Dynamite 二分KKK check(mid)&#xff1a; 能否选出mmm个点&#xff0c;使得 ∀i为关键点&#xff0c;Minjisselected{dis(i,j)}≤mid\forall i为关键点&#xff0c;Min_{j\ is\ selected}\{dis(i,j)\}\leq mid∀i为关键点&#xff0c;Minj is selecte…

【每日一题】7月6日精讲—平衡二叉树

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 平衡二叉树&#xff0c;顾名思义就…

【DP】晨练计划(ybtoj)

正题 ybtoj 题目大意 给你n个时间点 在第i个时间点跑步有aia_iai​点贡献&#xff0c;但会加一点疲惫值&#xff0c;疲惫值不能超过m 当前疲惫值为x&#xff0c;那么你可以花x点时间来清空疲惫值&#xff0c;当然也可以啥都不干 问你第n个时间后疲惫值为0的最大贡献 解题思…

MATLAB灰色预测

一.灰色预测 1.灰色系统下的灰色预测 <1>什么是灰色系统&#xff1f; 所谓的灰色系统其实就是夹杂在白色系统和黑色系统之中的一种系统&#xff0c;而白色系统就是全部信息已知的系统&#xff0c;黑色系统就是全部信息未知的系统。所以&#xff0c;夹在这两种系统中间…

ASP.NET Core 中的依赖注入

什么是依赖注入软件设计原则中有一个依赖倒置原则&#xff08;DIP&#xff09;&#xff0c;为了更好的解耦&#xff0c;讲究要依赖于抽象&#xff0c;不要依赖于具体。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。什么是依…

P4357-[CQOI2016]K远点对【K-Dtree】

正题 题目链接:https://www.luogu.com.cn/problem/P4357 题目大意 平面上给出nnn个点&#xff0c;求第kkk远的点对距离。 解题思路 K-Dtree\text{K-Dtree}K-Dtree的模板题&#xff0c;但是这里只有二维&#xff0c;大概是每次根据一个维度把nnn个点分成两半像线段树一样丢到下…

【每日一题】7月7日题目精讲—最短路

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 给一个连通图&#xff0c;每次询问…

【dfs】栅栏的木料(2012特长生 T4)

题目大意 给你n个木板&#xff0c;给你这些木板的长度&#xff0c;你可以把这些木板切开&#xff0c;现在有m个木料&#xff0c;问你最多可以切出多少个木料 解题思路 可以dfs枚举每个木料用哪个木板来切 但这样显然会超时&#xff0c;那么考虑剪枝 1.对于一些木板&#xf…

【c++算法刷题笔记】——洛谷1

2020/2/14-2/16 1. 循环提取一个数的每一位数字 while (d > 0) //d0跳出循环 {xd%10; //x每次为d的个位数 d d / 10; //相当于d每次舍去个位数 }2. cnew创建动态二维数组 int *anew int[n]; //创建动态一维数组 int(* a)[2…

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

P5325-[模板]Min_25筛

正题 题目链接:https://www.luogu.com.cn/problem/P5325 题目大意 定义一个积性函数满足f(pk)pk(pk−1)f(p^k)p^k(p^k-1)f(pk)pk(pk−1) 求∑i1nf(i)\sum_{i1}^nf(i)∑i1n​f(i) 解题思路 首先我们可以把f(pk)f(p^k)f(pk)是质数的情况拆成一个222阶的多项式f(x)x2−xf(x)x^2…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

【bfs】廉价最短路径(2013特长生 T4)

题目大意 给你一个图&#xff0c;每条边有一个代价&#xff0c;让你求0到1在最短路径的前提下的最小代价 解题思路 bfs同时求个最代价 代码 #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #de…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…