代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
typedef long long LL;
namespace IO
{
LL read()
{
LL s = 0; bool fu = false;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-') fu = true;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
s = (s << 1) + (s << 3) + (ch ^ 48);
ch = getchar();
}
return fu ? -s : s;
}
void write(LL x)
{
static int sta[20];
if (x < 0) putchar('-'), x = -x;
int tt = 0;
do
sta[tt ++ ] = x % 10,
x /= 10;
while (x);
while (tt) putchar(sta[ -- tt]^ 48);
}
}
using namespace std;
using namespace IO;
const int N = 500010;
struct Node
{
int l, r;
LL sum, d;
} tr[N << 2];
LL w[N];
LL gcd(LL x, LL y)
{
return y ? gcd(y, x % y) : x;
}
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[r] - w[l - 1];
tr[u] = {l, r, b, b};
}
else
{
tr[u].l = l, tr[u].r = 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 val)
{
if (tr[u].l == x && tr[u].r == x)
{
LL b = tr[u].sum + val;
tr[u] = {x, x, b, b};
}
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, val);
else modify(u << 1 | 1, x, val);
pushup(u);
}
}
Node query(int u, int l, int r)
{
if (l <= tr[u].l && tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
if (mid >= r) return query(u << 1, l, r);
else if (mid < l) 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;
}
}
int main()
{
int n = read(), m = read();
for (int i = 1; i <= n; ++ i)
w[i] = read();
build(1, 1, n);
char op[2]; LL x, y, d;
while (m -- )
{
scanf("%s", op);
x = read(), y = read();
if (op[0] == 'C')
{
d = read();
modify(1, x, d);
if (y + 1 <= n) modify(1, y + 1, -d);
}
else
{
auto left = query(1, 1, x);
Node right = {0, 0, 0, 0};
if (x + 1 <= y) right = query(1, x + 1, y);
write(abs(gcd(left.sum, right.d)));
putchar('\n');
}
}
return 0;
}
问题:
int main()
{
int n = read(), m = read();
for (int i = 1; i <= n; ++ i)
w[i] = read();
build(1, 1, n);
char op[2]; LL x, y, d;
while (m -- )
{
scanf("%s", op);
x = read(), y = read();
if (op[0] == 'C')
{
d = read();
modify(1, x, d);
if (y + 1 <= n) modify(1, y + 1, -d);
}
else
{
auto left = query(1, 1, x);
Node right = {0, 0, 0, 0};
if (x + 1 <= y) right = query(1, x + 1, y);
// 这里为什么不能写成 write(abs(gcd(left.sum, right.sum)));
// 或 write(abs(gcd(left.d, right.sum)));
// 或 write(abs(gcd(left.d, right.d)));
write(abs(gcd(left.sum, right.d)));
putchar('\n');
}
}
return 0;
}