算法学习专栏——线段树——最大gcd

题型三:求区间最大公约数

给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:

  1. C l r d,表示把 $A[l],A[l+1],…,A[r]$ 都加上 d。
  2. Q l r,表示询问 $A[l],A[l+1],…,A[r]$ 的最大公约数(GCD)。

对于每个询问,输出一个整数表示答案。

输入格式

第一行两个整数 N,M,。

第二行 N 个整数 A[i][]。

接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围

$N≤500000,M≤100000$
$1≤A[i]≤1018,$
$|d|≤1018,$
保证数据在计算过程中不会超过long long范围。

输入样例:

1
2
3
4
5
6
7
5 5
1 3 5 7 9
Q 1 5
C 1 5 1
Q 1 5
C 3 3 6
Q 2 4

输出样例:

1
2
3
1
2
4

思路(百度之星之后准备开视频讲解)

​ 这里我们可以这样思考.

​ 首先,前面基本的线段树的知识需要确保你已经基本掌握了,紧接着题目需要我们进行区间修改之后再求某些区间的GCD,但是我们是可以知道,修改某个区间的值后我们是无法直接对其进行pushup操作的,因为你对一个区间进行修改之后,假设$d = gcd(a, b, c)$,但是$gcd(a + 1, b + 1, c + 1)$和$d$是没有任何关系的.所以是无法直接修改的,但是如果单点修改的话,我们就可以直接pushup回溯操作即可.

​ 紧接着就是进行考虑如何进行区间操作??首先我们需要知道一个结论,$(a_1,a_2,…,a_n)=(a_1,a_2-a_1,a_3-a_2,a_4-a_3,…,a_n-a_{n-1})$(具体证明不做介绍),如此我们就可以通过维护一个差分数组然后求前缀和的方式来求gcd的数值

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/**
.@@
.@@@@
:--:::::::-----==: %%@@@%
:*++*+==--========----------:-==: @%@@@@.
.:. ..-=+=+*+==---=----------------------:*@%@@@@ .:..
.::::-----==+++====+***#+----=------:--------:-=%%@@@#+%@@@@@@@@@@@@@@@@@@@@@@@
:+%@@@@@@@@@@@@@@%::::=*=+++++=++==*%*=-:=*#+##=-----------------:::-@%@@@@@@@@@@@@@@@@@@@@@@@@@@@*
%%%%%%%%%%%%@@@@@@= .:=%@@@@@%#+=+++%@@@%+-==--++-=*=-------------:-----:*@@@@@@@@@@@@@@@@@@@@@@@@@@%
.@%%%%%%%%%@@@@%- .-+%@@@%@%%%####%#*#%%%%==----+=:-++-::------=----:::-:=@@@@@@@@@@@@@@@@@@@@@@@@%
%%%%%%%%@%@@+ .::*%@@@@%#**#####******+*%+===---+=..:==---------:---::::-@@@@@@@@@@@@@@@@@@@@@@@
%%%@%@%@@@: .:.%%%%%#=+*+*+*#*+=+***+*#+##=--=-:-+. ==--------::::--::-@@@@@@@@@@@@@@@@@@@@@
.#%%%@%@% . -@%%%*==+*++++**+++=+*++=++=+#--=----=: +---:-::::::::--:-%@@@@@@@@@@@@@@@@@@=
:@%%%@= . =%%%#---======+=========++=====*+--=-=--=. --::::::::::::--=@@@@@@@@@@@@@@@@@@@:
@%@# . -%%*+---========-:===++======-==-==--=-----: :-::::::::::::-=@@@@@@@@@@@@@@@@@@@=
@#. . .#*=+.-=-==-==-=-::===+=-==-=--=--==+=:------= .-:::::::-:--:--#@@@@@@@@@@@@@@@@@@#
- #+=-.:----=------.:-=-*===----==--==-+=-:::-::-: :-::::::::::::==+@@@@@@@@@@@@@@@@@@
. -==:..-=--==--:--:.-===+====----=====--=--::::::-- ::::::::::--:=%*=*@@@@@@@@@@@@@@@@.
.+: . .==-. :----==-::--:.---==-===---:------:----::::::-+ -:::------=--+#+#@@@@@@@@@@@@@@@@.
. . - ::--. .::---:-:.-=-: :--==--==:=--:-::::::--=-:::-:::*. :::-==-==--:--**@@@@@@@%@@@@@@@@@=
:.: :::.. .--:::::: --::.:-:---:--:--:::::::::--:==:::::::+. -:-=-=------:*+@@@@@@@@+ #@@@@@@
#-. -::.. .=+:::::-:.--:-:.::::::::::+:::::::::::::=-:::::::=. :=-=---------=%@@@@@@@@@ :@@@@
=@-. :=.. -=::::-:=.:::::-.::::::::::%.::::::::::::-=:::::::-+- *%+=-------::%@@@@@@@@@: :.
#@*. +-.. :-:::::::-..::::::.:::::::::%:-==:..::::::--+:::-:-==== :*%*+--------@@@@@@@@@@@
.@@# :=: .::::::::-:.::::::-.::::::.::#.:-=-.:..::-.::-+:-=--===-= -#++*+===-:#@@@@@@@@@@@@
*@@*. . --. .:::::::::-..::::.:::.::..:..-+:: :.......=-.::==--==-====- .**++++++=*@@@@@@@@@@@@@@:
=@@@==. .: .=-. ::::::.:::= .::::...::.-.....+::. - :....:*::--==--=======- -*++=+=++@@@@@@@@@@@@@@@@@@%-
+@@@@::- . .:- :=-. .::::::.::=- .::......=.=.....+ :. : ... - -:-==+---==-=--*: . .*++++=+%@@@@@@@@@@@@@@@
:@@@@%.=.. : :--.-=:..:.::.:....- ......... --: ::.:. . :::.- ----=#+====-==-*. :*++=++@@@@@@@@@@@@@.
+*#-- :.:: :-::==..::.:..:...:: .:....... . :: :. :. -::. ..:#=-=+-==-===-=+.+ .. -+=++%#=-+=%@@@@#
. ...::.--::==: ::........-:..=- : . . . .:. :-*- .:=-+====-==--=-+# :. +++++==+++++*@@*
:.::.::-.-==-.=-:...--.: :.::-. : .: :+--:. ::.==+===---=-=+--%. +@@=. :=*+++++++*++*
.::::::::==---=-:.. =- . ..: :..: .:... : -. .+. -*=:.+@@@@@@@@*====---=+*:**. . =@@**%+:-+*%*++***+=
. ...::::::-+=--+-=:--.+:. .. :.-.:::::. .: :.*. :-:+#@@%#++=%:-@##+===-==-=+--==+ .. .###*+++**#@%#+*+++*=
..::::::::.*+--:=-----:=:-....::=:--=:....:..=. :. ..+@@@*+==---#-=@*+*====-===+:-=*@% :: *#*+*#+*++#%%%%##*+++-
.::.:::::::%=--:-------: . : -:-+#+-....= ..: -*#::%+-:=+---:+**-+==-===-=-+-=@@@@ -# =***#%#+*+#%==*+
:.:::::::::-+=:---=-----. . :. ::=..:..: . : -=--:..:--+#-:-+=======-%==#@@@@:.@= :#***%%#*+=#-==
:-::-::::.:--*:---=-=---: . ..-+*#%#=-+:...:. :+-....-+=::::#=======-*%-+@@@%@@-%%- .#++*%%#*+#*+-
. =-:::=:::::-:+.:--=-=--:- .=**+-:::+++%-..:. . ::..--:....:=#-=====-#@+=@@@%*%@%%@%- -*+#%:*%++*=
=:::---:------::-:==-=--+. ....: :.:. . ......::*=-====-*@#-%@@%#*%%%%%%@*. +**- .*#**=
+:::. :---=--=:=:-:==-==-:@. .....:. ..:. ...::...--:*=====-+@@-*@%%*##%%*###+#*= +- ::-:**
::-: .:---.#:=.:-==-==-:%% .... ..: : := ==-+==-*@@=*@%#**#%#****##*++**- .: .
.-- .:--:=:=-.-==-==-:%@+ .... .: :: :=--===#@@**%%**#*##***++**+=+*- ::
:. :----=.- -=-====-%@@: ... . . . :---==-@@@#%%%#*#*******+++***+# :
. -:--: .:-+--==-:%@@@ . #%:-===@@@#%##*##**+++#*+*+*+****-
::-: *:%==----*+%@% . . #@%--+=*@%@%%##**#**+++%#*==+*++*+=
-=$:-. #:+#+---:#%++%#. . .:. .:+ ..#@@@--**%%%%%###*+#++*++*--+*==+++-+.
. =:: -==%@--=-=%**%%+ =@+ .....:.:.:. .*:@@%--%%@%%%####**#++*+++--: .+*-==
:---+**%%---:@**%%#+ . :@%%%::.:::::..:.: .-::%%%-:@%%%%%###**#*+++=*+-:: :==:-=
. :=-+*##*#:-:**+*%**@: =@#*:.:::::::::: .:...:@%%-+%%%%%###**+%*==+=%=:-. .. :.
. +*=+**%**-:=***##*+%%. . .*%.:::::::::.. :. ....@%%=%%%#*#####+#%+===+:-:-. .
.+-++**#+** +*-*++++%%%. .. --:.::.::: =: . .%%#+%%####*+@*++%+=-+. .:-
--++=**#*+*-++==+++%%%#@+.. .:::. :=. . .%%%#*#*##*#+#=++#===: .-
. . =-=+****+**+#:+==++#%%#%%%@%=. .. :-: . %#%###%*##.:*+==#++- :
. :-=+=++***++#-:+++*++*#%%%%@@%=.. .. :---. #@@%@@@@= := .+-+-
. . :.-===++**+==*+::+#++++*#%%%%%%%%-. .*=:-:. *%%%##*==+**#*+==*+=
: -::====++*=+=+*==*=-=#**##%#%%%%%*+-:%#--:-. .. .%#*=-==-*#*++==++-=#*:
:*::**=====+**==+=++*##*+++**##%%%%%%. :::.:. .. .:=--===+@#*+++=+*+=-=+=*#=
#-=+==*=-++++#++==-++++*++++*#%%%%%%=- .:.... . . -=--=+@#*#%@@%+==+=====+*+
..*++==+**+:=*++%++++#++++++*+**#%%%%#-=. .:........ .@-=+++#%%@@%@=======++*@+
.+-.-+*==*++#+-:=++*%+=**++++++*++**%%%%--=-.::.......... .: ==++*%@@%@+========+*#@@+
-:--.=-*+*+++++=:.:-+*#+++*****=+*##%+#%==---::........... : .+%@@@%@#+======++*#%%@@#%=
+::-:==--=*==**=#=:::-+#**+*+**++**%=.-++-:::--... .. .... :. ..-@@@*++====++++*#%@@@%*=+.
=---.=--:*+=+#*+=:-:--=++=**+++++*#+:=-.--:.:::.......... + ..*%-+=-====+++*###@@@#+=+#*
=----==-*+===@%:..-=---++##=+++***#-. .:=::...:.......... := :*:==-=====+++*%#%@@*++++##@*
.+=-=*=+#*---==%:.:-=%+#+-:--+++*+*%:.. -::............. :. .--==-=======+*#*%@%+++==+##@#%+
-:=##*+=-::-===+:.--+*#---::+*++++#+ ....- .:......... .. . :+. . =============+**#*++++===*%%#%###.
:--*#@*+-::::-==-:-=#=.---:-+*==+#-......-: .......... :. +============+*##**++====*%%%#**+=+
.:---%=@*+-::--:-:.-*=:=:--=#++*@%-... . .-:.... ...... .:. .=-===========+**+++===-===*#***+++=-:
..:-==+*#+*=:-::--.=+=::-=+*+%@+#@%.... ..-:. ......... .- .+============++========--===++**++==--
.:----++%**-:: .+=+=++++++*%#+@@@%......-:. . =. . .+-===-===-==++==--===------==+++====--:
..:--=*#%*+= .=%##-:-+++*##+@@@@@.... -:. . ..- -+==-======++*=======------==++======+*#*
.::=-=#+#- .::=#-:-:=++=+##*@@@@@@.. .::. . -: . .=+==-==+-==++=:=---=----========+**+=----:=
.::--=+#=.:::-*=:::::++=+*#*%.#@@@@:..::. . . .+ .=#*++++*+=====--=-=---=--=+**##*+=====-------:-
..::-=*+::::=:.::::--===**+*. -@@@@:.:: ... . -.. . . .-%@@@*+*#*#*+====--=-:----*##*+==--==---======----:
..:-:+:-:--:::--:::-+#*+++: @@@@+:- .. . +. .. -@@@@@@@*@%*###*======*+-=-=%#=-=======-====-=======-:-+
..:=::::::::::-:**++=-++. .@@@@#= . . :+ :#@@@@@@@@@%##%%%%#+++==#@%%@=**+==========-------=====-=+==
. .:::::::--+==----+#++. .@@@@@ .. ..:::+#%@%@@@@@@@#@%%%%%%@%*=+#@@@%@#%@=============------=====++++=+
.... ..::=-:----+*=+**=++@@@@@:.-*@@%%%%%@@@@*: . .@@%%@%%@%**%@@@@@##@@*========--------=====+++*#*+==
. ...::=:--==++=+++=+++%@@@@@@@%%@%@@#- :%#%%%%@%#@@@@@@@%#@*@@+--===-----------======*##**=--
...:.--:--=*+===++=++=#@@@@@%%%#*++=. :%%%@@%%@@@@@@@@+@@#+*@@+===-----------====+++*##**+=-:
....:+=:-==#++===+++===%@@%#*+==+++++++*##@@@%@@@@@@@@@**%##+=-%@#=-------------====+++*##*++=-:.
..:-+#===+# .-:=+=*+*+#*+==+++++++++**%@@@@@@@@@@@*-@@#+=+==+@@=--------------===+++*##*+=-:.
..:=%+==+% =#*-##*#+=%+++=++*+#%@@@@@@@@@@:%@#*=+=-+=#@@+-=-------------====+*#*++=-:.
.=*===* .--#:..-#@@-. .:=**@@@@@@@@*@@@%+%+@@=--#@%=--:----------------=+++==-:.
=::-- :*-##==-. -@@@@@@@@@@@@@@@@@@@@@%+=::::::::::::::::::--====-:..
... *%=-..... %@@@@@@@@@@@@@@@@@@@@@*-::..:.............:::--:.. .-:
:: ==. ..... +@%@@@@@@@@@@@@@@@@@@@@*.:. . ... .... . =@*-:
::..:---::... :#*#@@@@@@@@@%%@@@@@@@@@@+ . :* ##+%+:
...::::*-:::@@@@@@%##%%%%@@@@@@@# -+. *+ = -:
.. .#@@%%%%##*+*#%@@@%%%= . : ::
@@@%%%######%%%%#####%= = #
@@@@@%@@%%%###*##*- . . =
:@@%%%%###******+=- .
*@###***+**+++:
-*- =*++*:

*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <unordered_map>
#include <string>
#include <cmath>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <cstdio>
#include <iomanip>

// #define int long long
#define ull unsigned long long
#define ed '\n'
#define fi first
#define se second
#define fore(i, l, r) for(int i = (int)(l); i <=(int)r; i++)
#define debug(x) cout << "#x = " << x << ed;
#define PI acos(-1)
#define E exp(1)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define me0(st) memset(st, 0, sizeof st)
#define me3f(st) memset(st, 0x3f, sizeof st)
#define pdf(x) printf("%lf", double(x))
#define pif(x) printf("%d ", int(x))
#define scf(x) printf("%d", int(x))
#define re return 0
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define out(x, k) cout << fixed << setprecision(k) << x << ed

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;
typedef double db;

const int INF = 1e9;
const int N = 5e5 + 10;

struct Node {
int l, r;
LL sum, d;
}tr[4 * N];
LL w[N];

LL gcd(LL a, LL b) {
return b == 0 ? a : gcd(b, a % b);
}

void pushup(Node &u, Node &l, Node &r) {
u.sum = l.sum + r.sum;
u.d = gcd(l.d, r.d);
}

void pushup(int u) {
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r) {
if (l == r) {
LL b = w[l] - w[l - 1];
tr[u] = {l, r, b, b};
} else {
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}

void modify(int u, int x, LL v) {
if (tr[u].l == x && tr[u].r == x) {
LL b = tr[u].sum + v;
tr[u] = {x, x, b, b};
}
else {
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}

Node query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
else{
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
else if (l > mid) return query(u << 1 | 1, l, r);
else {
auto left = query(u << 1, l, r);
auto right = query(u << 1 | 1, l, r);
Node res;
pushup(res, left, right);
return res;
}
}
}
void solve() {
int n, m;
scanf("%d%d", &n, &m);
fore (i, 1, n) scanf("%lld", &w[i]);
build(1, 1, n);

int l, r;
LL d;
char op[2];
while (m -- )
{
scanf("%s%d%d", op, &l, &r);
if (*op == 'Q')
{
auto left = query(1, 1, l);
Node right({0, 0, 0, 0});
if (l + 1 <= r) right = query(1, l + 1, r);
printf("%lld\n", abs(gcd(left.sum, right.d)));
}
else
{
scanf("%lld", &d);
modify(1, l, d);
if (r + 1 <= n) modify(1, r + 1, -d);
}
}
}

int main()
{
// IOS;
int _ = 1;
// cin >> _;

while(_--) {
solve();
}
return 0;
}