题目大意:要我们对一段区间进行两种操作:1.区间加法,2.查询区间gcd。
看到有区间修改的操作,首先考虑用线段树,这样可以方便的维护区间修改的操作,但是区间gcd是会随着区间修改而时刻变化的,比如:区间为2,4,6,此时的区间gcd是2,但是如果给这个区间的每一个数都加上一个1,就变成了3,5,7此时的区间gcd为1.所以很难直接维护。但是呢,gcd是有一个很重要的性质的,就是gcd(a,b)=gcd(a−b,b).
就因为这个结论,我们就可以把区间gcd(a,b,c,d)转化为gcd(a,b,c−d,d),gcd(a,b−c,c−d,d),gcd(a−b,b−c,c−d,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__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!