思路:
首先根据更相减损术,我们得到一个结论:
\(gcd(a_l, a_{l+1}, ...,a_r) = gcd(a_l, a_{l+1}-a_l, a_{l+2}-a_{l+1}, ..., a_r-a_{r-1})\) 于是我们用线段树维护差分数组,树状数组维护每个位置的值,然后查询就是
\(gcd(a_l+bit.sum(l), segtree.query(l+1, r))\)。
代码:
#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#include using namespace std;#define y1 y11#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb emplace_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pli pair #define pii pair #define piii pair #define pdd pair #define mem(a, b) memset(a, b, sizeof(a))#define debug(x) cerr << #x << " = " << x << "\n";#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//headconst int N = 5e5 + 5;int n, m, l, r;LL a[N], d;char op[15];LL tree[N<<2];struct BIT { LL bit[N]; void add(int x, LL a) { while(x <= n) bit[x] += a, x += x&-x; } LL sum(int x) { LL res = 0; while(x) res += bit[x], x -= x&-x; return res; } void init() { for (int i = 1; i <= n; ++i) bit[i] = 0; }}B;inline void push_up(int rt) { tree[rt] = __gcd(tree[rt<<1], tree[rt<<1|1]);}LL query(int L, int R, int rt, int l, int r) { if(L > R) return 0; if(L <= l && r <= R) return tree[rt]; int m = l+r >> 1; LL res = 0; if(L <= m) res = __gcd(res, query(L, R, ls)); if(R > m) res = __gcd(res, query(L, R, rs)); return abs(res);}void update(int p, LL d, int rt, int l, int r) { if(p > r) return ; if(l == r) { tree[rt] += d; return ; } int m = l+r >> 1; if(p <= m) update(p, d, ls); else update(p, d, rs); push_up(rt);}void build(int rt, int l, int r) { if(l == r) { tree[rt] = a[l]-a[l-1]; return ; } int m = l+r >> 1; build(ls); build(rs); push_up(rt);}int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]); build(1, 1, n); B.init(); while(m--) { scanf("%s", op); if(op[0] == 'C') { scanf("%d %d %lld", &l, &r, &d); B.add(l, d); update(l, d, 1, 1, n); B.add(r+1, -d); update(r+1, -d, 1, 1, n); } else { scanf("%d %d", &l, &r); printf("%lld\n", __gcd(a[l]+B.sum(l), query(l+1, r, 1, 1, n))); } } return 0;}