区间最大公约数
给定长度为N的数列A,以及M条指令,指令为一下两种之一:
1. C L R d 表示把A[L],A[L+1].....A[R]都加上d
2. Q L R 表示查询 A[L]......A[R]的最大公约数
对于每个询问输出一个答案;
这个题算是经典的线段树的问题了,因为:区间修改+区间查询
这道题好就好在可以用差分的思维来代替懒标记
这样区间修改就变成了单点修改,在A[L]+d,A[R+1]-d
之所以可以用差分来代替是因为(a,b,c) = (a,b-a,c-b)
以此类推我们可以得到,只要我们得知a的值就可以递推出b-a,c-b的值,所以我们构造b[n]来存储差分
1 # include<iostream>
2 # include<algorithm>
3 # include<cstring>
4 # define int long long
5 # define endl "\n"
6 using namespace std;
7 const int N = 5e5+10;
8 struct node{
9 int l,r;
10 int sum,d;
11 }tr[N*4];/*l,r区间范围
sum差分数组
d区间最大公约数
*/
12 int w[N],n,m;
13
14 int gcd(int a,int b){
15 return b?gcd(b,a%b):a;
16 }
17
18 void pushup(node &u,node &l,node &r){
19 u.sum = l.sum+r.sum;
20 u.d = gcd(l.d,r.d);
21 }
22
23 void pushup(int u){
24 pushup(tr[u],tr[u<<1],tr[u<<1|1]);
25 }
26
27 void build(int u,int l,int r){
28 if(l == r){
29 int b = w[r]-w[r-1];/*差分*/
30 tr[u] = {l,r,b,b};
31 return;
32 }
33 tr[u] = {l,r};
34 int mid = l+r>>1;
35 build(u<<1,l,mid),build(u<<1|1,mid+1,r);
36 pushup(u);/*向上更新*/
37 }
38
39 void modify(int u,int x,int v){
40 if(tr[u].l == x&&tr[u].r==x){
41 int b = tr[u].sum+v;
42 tr[u]={x,x,b,b};
43 return;
44 }
45 int mid = tr[u].l+tr[u].r>>1;
46 if(x<=mid){
47 modify(u<<1,x,v);
48 }
49 else{
50 modify(u<<1|1,x,v);
51 }
52 pushup(u);
53 }
54
55 node query(int u,int l,int r){
56 if(tr[u].l>=l && tr[u].r<=r){
57 return tr[u];
58 }
59 int mid = tr[u].l+tr[u].r>>1;
60 if(r<=mid) return query(u<<1,l,r);
61 else if(l>mid) return query(u<<1|1,l,r);
62 else{
63 auto left = query(u<<1,l,r);
64 auto right = query(u<<1|1,l,r);
65 node res;
66 pushup(res,left,right);
67 return res;
68 }
69 }
70 signed main(){
71 ios::sync_with_stdio(false);
72 cin.tie(0);
73 cout.tie(0);
74 cin>>n>>m;
75 for(int i = 1; i <= n;++i) cin>>w[i];
76 build(1,1,n);
77
78 int l,r,d;
79 char op[2];
80 while(m--){
81 cin>>op>>l>>r;
82 if(*op == 'Q'){
83 auto left = query(1,1,l);
84 node right = {0,0,0,0};
85 if(l+1<=r) right = query(1,l+1,r);
86 cout<<abs(gcd(left.sum,right.d))<<endl;
87 }
88 else{
89 cin>>d;
90 modify(1,l,d);
91 if(r+1<=n) modify(1,r+1,-d);
92 }
93 }
94
95
96 return 0;
97 }
所以最后我们想要得到的答案就是gcd(a1,gcd(b-a,c-b,d-c....))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】