博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AcWing 246. 区间最大公约数
阅读量:5337 次
发布时间:2019-06-15

本文共 2231 字,大约阅读时间需要 7 分钟。

思路:
首先根据更相减损术,我们得到一个结论:
\(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;}

转载于:https://www.cnblogs.com/widsom/p/11259953.html

你可能感兴趣的文章
字符串替换 方法讨论
查看>>
Hibernate学习-在线书城后台管理系统的设计
查看>>
CentOS环境安装Docker配置nginx+uwsgi+django
查看>>
HDU 2188.悼念512汶川大地震遇难同胞——选拔志愿者-巴什博奕
查看>>
mybatis源码解析之Configuration加载(五)
查看>>
python--用python操作Git
查看>>
sscanf函数——强大的C语言库函数
查看>>
图像和流媒体 -- 帧率、分辨率、码流的概念和关系(转)
查看>>
数论 青蛙的约会 扩展欧几里得
查看>>
struts2.1笔记05:struts2开发环境的搭建
查看>>
GUI编程笔记(java)11:使用Netbeans工具进行GUI编程
查看>>
函数名可以作为函数的返回值
查看>>
C代码中如何调用C++ C++中如何调用C
查看>>
webx学习
查看>>
eclipse导出可供项目引用的jar
查看>>
(16)JavaScript的流程控制(js的循环)
查看>>
java之equals()和hashCode()方法
查看>>
十进制转换为二进制(一直不会算的)
查看>>
Linux源码编译安装php7.3
查看>>
CF997B Roman Digits
查看>>