盐城市建设局网站,网站关键词seo优化公司,百度网页链接,免费的模板下载246. 区间最大公约数
246. 区间最大公约数 - AcWing题库 给定一个长度为 N 的数列 A#xff0c;以及 M 条指令#xff0c;每条指令可能是以下两种之一#xff1a;
C l r d#xff0c;表示把 A[l],A[l1],… 都加上 d。Q l r#xff0c;表示询问 A[l],A[l1],… 的最大公约… 246. 区间最大公约数
246. 区间最大公约数 - AcWing题库 给定一个长度为 N 的数列 A以及 M 条指令每条指令可能是以下两种之一
C l r d表示把 A[l],A[l1],… 都加上 d。Q l r表示询问 A[l],A[l1],… 的最大公约数(GCD)。
对于每个询问输出一个整数表示答案。
输入格式
第一行两个整数 N,M。
第二行 N 个整数 A[i]。
接下来 M 行表示 M 条指令每条指令的格式如题目描述所示。
输出格式
对于每个询问输出一个整数表示答案。
每个答案占一行。
数据范围
N≤500000,M≤100000, 1≤A[i]≤10^18, |d|≤10^18, 保证数据在计算过程中不会超过 long long 范围。
输入样例
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
4 解析
根据lyd的《算法进阶指南》
通过辗转相减法可知gcd(x,y)gcd(x,y-x)。可以进一步拓展为三个数gcd(a,b,c)gcd(a,b-a,c-b);
以此类推询问“Q,l, r就相当于求gcdA[l],ask(1,l1,r));
注意特殊情况
if (l r) {printf(%lld\n, gcd(t, ask(1, l 1, r)));
}
else {printf(%lld\n, t);
}
否则ask(1,l1,r),当l1r时会出错
#includeiostream
#includecstdio
#includecstdlib
#includestring
#includecstring
#includecmath
#includectime
#includealgorithm
#includeutility
#includestack
#includequeue
#includevector
#includeset
#includemap
using namespace std;
typedef long long LL;
const int N 5e5 5;struct node {int l, r;LL dat,v;
}t[4*N];int n, m;
LL arr[N];LL gcd(LL a, LL b) {a a 0 ? -a : a;b b 0 ? -b : b;if (b 0) {return a;}return gcd(b,a%b);//return __gcd(a, b);
}void build(int p, int l, int r) {t[p].l l, t[p].r r;if (l r) {t[p].dat arr[l] - arr[l - 1];t[p].v arr[l] - arr[l - 1];return;}LL mid (l r) / 2;build(p * 2, l, mid);build(p * 2 1, mid 1, r);t[p].dat gcd(t[p * 2].dat, t[p * 2 1].dat);t[p].v t[p * 2].v t[p * 2 1].v;
}void change(int p, int y, LL x) {if (t[p].l t[p].r) {t[p].dat x;t[p].v x;return;}LL mid (t[p].l t[p].r) / 2;if (y mid)change(p * 2, y, x);if (y mid)change(p * 2 1, y, x);t[p].dat gcd(t[p * 2].dat, t[p * 2 1].dat);t[p].v t[p * 2].v t[p * 2 1].v;
}LL ask(int p,int l,int r) {if (l t[p].l r t[p].r) {return t[p].dat;}LL mid (t[p].l t[p].r) / 2;if (l mid r mid) {return gcd(ask(p * 2, l, mid), ask(p * 2 1, l, r));}else if (l mid) return ask(p * 2, l, r);return ask(p * 2 1, l, r);/*if (r mid) return ask(p * 2, l, r);else if (l mid)return ask(p * 2 1, l, r);else gcd(ask(p * 2, l, r), ask(p * 2 1, l, r));*/
}LL ask1(int p,int l,int r) {if (l t[p].l r t[p].r) {return t[p].v;}LL mid (t[p].l t[p].r) / 2;LL val 0;if (l mid)val ask1(p * 2, l, r);if (r mid) val ask1(p * 2 1, l, r);return val;
}int main() {scanf(%d%d, n,m);for (int i 1; i n; i) {scanf(%lld, arr[i]);}build(1, 1, n);char op[2];int l, r;LL d;while (m--) {scanf(%s%d%d, op, l, r);if (op[0] C) {scanf(%lld, d);change(1, l, d);if(r1n)change(1, r 1, -d);}else {LL t ask1(1, 1, l);if (l r) {printf(%lld\n, gcd(t, ask(1, l 1, r)));}else {printf(%lld\n, t);}}}return 0;
}