维护区间修改和区间最大公约数(线段树)

  题目大意:要我们对一段区间进行两种操作:1.区间加法,2.查询区间gcd
  看到有区间修改的操作,首先考虑用线段树,这样可以方便的维护区间修改的操作,但是区间gcd是会随着区间修改而时刻变化的,比如:区间为2,4,6,此时的区间gcd2,但是如果给这个区间的每一个数都加上一个1,就变成了3,5,7此时的区间gcd1.所以很难直接维护。但是呢,gcd是有一个很重要的性质的,就是gcd(a,b)=gcd(ab,b).
  就因为这个结论,我们就可以把区间gcd(a,b,c,d)转化为gcd(a,b,cd,d),gcd(a,bc,cd,d),gcd(ab,bc,cd,d)最后我们要维护的区间gcd也就成了维护一个原数组的一个差分数组,同时我们知道差分数组最后前面的x项全部加起来才是原来的x项,所以我们这个时候也可以把区间修改操作转化成对这个区间的两个端点进行单点修改的操作,也就是左端点加x,右端点x抵消掉它们对其他区间的影响.

struct SegmentTree { int val[N << 2]; int gcd[N << 2]; void pushup(int u) { val[u] = val[u << 1] + val[u << 1 | 1]; gcd[u] = std::__gcd(gcd[u << 1], gcd[u << 1 | 1]); } void build(int u, int l, int r) { if (l == r) { val[u] = a[l], gcd[u] = a[l]; return ;} int mid = (l + r) >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); pushup(u); } void modify(int u, int l, int r, int x, int v) { if (l == r) { val[u] += v; gcd[u] += v; return ; } int mid = l + r >> 1; if (x <= mid) modify(u << 1, l, mid, x, v); else modify(u << 1 | 1, mid + 1, r, x, v); pushup(u); } int GCD(int u, int l, int r, int ln, int rn) { if (ln <= l && rn >= r) return gcd[u]; int mid = l + r >> 1; if (rn <= mid) return GCD(u << 1, l, mid, ln, rn); else if (ln > mid) return GCD(u << 1 | 1, mid + 1, r, ln, rn); else return std::__gcd(GCD(u << 1, l, mid, ln, rn) , GCD(u << 1 | 1, mid + 1, r, ln, rn)); } int query(int u, int l, int r, int ln, int rn) { if (ln <= l && rn >= r) return val[u]; int mid = l + r >> 1; if (rn <= mid) return query(u << 1, l, mid, ln, rn); else if (ln > mid) return query(u << 1 | 1, mid + 1, r, ln, rn); else return query(u << 1, l, mid, ln, rn) + query(u << 1 | 1, mid + 1, r, ln, rn); } }SGT;

__EOF__

本文作者HoneyGrey
本文链接https://www.cnblogs.com/Haven-/p/16253234.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   浅渊  阅读(165)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示