首页 > 其他分享 >势能线段树

势能线段树

时间:2025-01-16 22:32:02浏览次数:1  
标签:势能 undef log int 线段 mid rson define

简介

通过定义势能函数 \(\phi(i)\) 去描绘整个序列的势能从而推导正确的复杂度。

例题

P4145 上帝造题的七分钟 2 / 花神游历各国

典。

设 \(\phi(i)\) 表示第 \(i\) 个元素的势能。

一个元素不停的开根一定会变成 \(1\),不妨将元素 \(x\) 改写成 \(2^k\) 的形式。一次开根会将 \(k\) 砍半,因此 \(\phi(i) = \log \log V\)。

放在线段树上,维护区间最大值即可。

时间复杂度 \(O(n \log n \log \log V)\)。

代码:

namespace Segment_Tree {
	#define mid (L + R) >> 1
	#define son p, L, R
	#define lson ls(p), L, (L + R) >> 1
	#define rson rs(p), ((L + R) >> 1) + 1, R

	int mx[N << 2], sum[N << 2];

	inline int ls(int p) {
		return p << 1;
	}

	inline int rs(int p) {
		return p << 1 | 1;
	}

	inline void psup(int p) {
		mx[p] = max(mx[ls(p)], mx[rs(p)]);
		sum[p] = sum[ls(p)] + sum[rs(p)];

		return ;
	}

	inline void build(int p = 1, int L = 1, int R = n) {
		if(L == R) {
			mx[p] = sum[p] = a[L];

			return ;
		}

		build(lson), build(rson), psup(p);

		return ;
	}

	inline void add(int l, int r, int p = 1, int L = 1, int R = n) {
		if(mx[p] <= 1) return ;

		if(L == R) {
			sum[p] = sqrt(sum[p]);
			mx[p] = sqrt(mx[p]);

			return ;
		}

		if(l <= mid) add(l, r, lson);
		if(r > mid) add(l, r, rson);

		psup(p);

		return ;
	}

	inline int query(int l, int r, int p = 1, int L = 1, int R = n) {
		if(l <= L && R <= r) return sum[p];

		int res = 0;

		if(l <= mid) res += query(l, r, lson);
		if(r > mid) res += query(l, r, rson);

		return res;
	}

	#undef mid
	#undef son
	#undef lson
	#undef rson
}

P9989 [Ynoi Easy Round 2023] TEST_69

Ynoi!不过是 Easy Round。

还是设 \(\phi(i)\) 表示第 \(i\) 个元素的势能。

注意到每次有效操作至少会除去 \(2\) 这个最小的因子,由此得出 \(\phi(i) = \log V\)。

在线段树上维护区间 \(\operatorname{lcm}\) 判断是否与给出的数 \(x\) 有整除关系即可。

时间复杂度 \(O(n \log n \log V)\)。

namespace Segment_Tree {
	#define mid (L + R) >> 1
	#define son p, L, R
	#define lson ls(p), L, (L + R) >> 1
	#define rson rs(p), ((L + R) >> 1) + 1, R

	int sum[N << 2];
	__int128 lcm[N << 2];

	inline __int128 Lcm(__int128 x, __int128 y) {
		return x / __gcd(x, y) * y;
	}

	inline int ls(int p) {
		return p << 1;
	}

	inline int rs(int p) {
		return p << 1 | 1;
	}

	inline void psup(int p) {
		sum[p] = (sum[ls(p)] + sum[rs(p)]) % mod;
		if(Lcm(lcm[ls(p)], lcm[rs(p)]) <= 1e18) lcm[p] = Lcm(lcm[ls(p)], lcm[rs(p)]);
		else lcm[p] = 1e18;

		return ;
	}

	inline void build(int p = 1, int L = 1, int R = n) {
		if(L == R) {
			sum[p] = lcm[p] = a[L];

			return ;
		}

		build(lson), build(rson), psup(p);

		return ;
	}

	inline void add(int l, int r, int k, int p = 1, int L = 1, int R = n) {
		if(Lcm(lcm[p], k) == k) return ;

		if(L == R) {
			sum[p] = __gcd(sum[p], k);
			lcm[p] = sum[p];

			return ;
		}

		if(l <= mid) add(l, r, k, lson);
		if(r > mid) add(l, r, k, rson);

		psup(p);

		return ;
	}

	inline int query(int l, int r, int p = 1, int L = 1, int R = n) {
		if(l <= L && R <= r) return sum[p];

		int res = 0;

		if(l <= mid) res = (res + query(l, r, lson)) % mod;
		if(r > mid) res = (res + query(l, r, rson)) % mod;

		return res % mod;
	}

	#undef mid
	#undef son
	#undef lson
	#undef rson
}

标签:势能,undef,log,int,线段,mid,rson,define
From: https://www.cnblogs.com/endswitch/p/18675865

相关文章

  • 线段树合并
    简介将多棵线段树的信息统一起来的高效算法称之为线段树合并。通常合并顺序呈树状结构。例题P3224[HNOI2012]永无乡假设所有点都在一个连通块里,那么我们只需要维护一个值域线段树并在上面二分即可。但此时图不连通,我们该如何快速的统计信息呢?对于连边,并查集可以胜任。对......
  • 洛谷题单指南-线段树的进阶用法-P3168 [CQOI2015] 任务查询系统
    原题链接:https://www.luogu.com.cn/problem/P3168题意解读:一个任务管理系统,能够查询在某个时间点运行的任务中优先级最小的k个任务的优先级之和。解题思路:由于总时间n不超过100000,考虑针对所有时刻建立可持久化线段树,根节点为root[i]的线段树维护时刻i的任务情况,节点区间表示......
  • 洛谷题单指南-线段树的进阶用法-P2617 Dynamic Rankings
    原题链接:https://www.luogu.com.cn/problem/P2617题意解读:动态求区间第k小问题。解题思路:树套树的典型应用,具体阐述参考:https://www.cnblogs.com/jcwy/p/18640914100分代码:#include<bits/stdc++.h>usingnamespacestd;constintN=100005;structOp{charop;......
  • 2024中国网络安全产业势能榜优能企业「运营商行业」典型案例展示
    运营商作为通信和网络服务的提供者,其安全性直接影响到全球范围内的信息流通与互联网基础设施的稳定。随着5G、云计算等新兴技术的普及,运营商面临着更高的安全压力。本期将展示运营商在加强网络防护、提升数据安全等方面的创新实践,以保障全球信息传输的安全性。PS:典型案例展示排名......
  • 解题报告-论对“线段树思想”的新理解
    解题报告-论对“线段树思想”的新理解一晚上刷了两个线段树知识点,也是见识到了线段树世界的博大精深。我们发现无论怎么写线段树,大体框架都是一样的。那么为什么有那么多种线段树呢?一个是线段树标记的不同。在李超线段树中,每个结点维护的是当前结点最上面那条线的编号,于是更新......
  • 线段树学习笔记
    什么是线段树线段树是一种基于分治思想的二叉树结构,用于在区间上进行信息统计,比树状数组更为通用、直观,支持单点修改、区间修改、区间查询。线段树维护的数据具有可并性,比如区间和、区间积、区间最值等等。模板建树voidbuild(intl,intr,intp){ tre[p].l=l;tre[p].r=r;......
  • 线段树【区间GCD】
    https://codeforces.com/contest/2050/problem/F#include<bits/stdc++.h>#definelcp<<1#definercp<<1|1#defineINF2e9usingnamespacestd;#definelowbit(x)x&(-x)#defineendl'\n'usingll=longlong;usingpii=pair......
  • 64.在Vue3中使用OpenLayers显示带箭头的线段,箭头居中
    在WebGIS开发中,使用OpenLayers渲染地图和矢量图形是常见的需求。今天我们来实现一个效果:在Vue3项目中,使用OpenLayers显示带箭头的线段,并让箭头居中。项目环境和技术栈Vue3+CompositionAPIOpenLayersVite构建工具实现效果我们将绘制一条由多个坐标点构成的线......
  • 线段树入门讲解
    有一段时间没有更新了,前面比较忙,所以知识上会有一些跳跃,后面看看有没有时间去补一下吧,没有就算了那现在就开始说一下线段树线段树是一种数据结构,他主要是用于实现快速的区间修改和区间求和这两个功能,同时,有别于树状数组,线段树还有更多的是在于其功能的强大和灵活性上,就比如说,树......
  • 线段树分治-学习笔记
    线段树分治-学习笔记阅前须知:本文给出了线段树分治的一道例题以及多道习题,同时给出了部分实现的代码,帮助学习线段树分治。总述线段树分治是一种离线算法,在于把修改挂在线段树的节点上,通过遍历线段树求出每个叶子节点的答案,以减小复杂度。例题P5787二分图题目大意:\(n\)个点......