线段树 FZU 2201 序列操作

来源:互联网 发布:信息技术软件介绍ppt 编辑:程序博客网 时间:2024/05/17 07:12

把gcd转化成差值...然后建立两颗线段树....

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm>#include <cstring>#include <climits>#include <cstdlib>#include <cmath>#include <time.h>using namespace std;typedef long long LL;#define lson o << 1, L, mid#define rson o << 1 | 1, mid+1, R#define ls o << 1#define rs o << 1 | 1const LL INF = 1e18;const int maxn = 100005;LL g[maxn << 2];LL val[maxn << 2];LL lazy[maxn << 2];LL add[maxn << 2];LL a[maxn];LL b[maxn];int n, m;void pushup(int o){g[o] = __gcd(g[ls], g[rs]);}void pushdown(int o){if(lazy[o]) {lazy[ls] ^= lazy[o];lazy[rs] ^= lazy[o];add[ls] = -add[ls];add[rs] = -add[rs];val[ls] = -val[ls];val[rs] = -val[rs];lazy[o] = 0;}if(add[o]) {add[ls] += add[o];add[rs] += add[o];val[ls] += add[o];val[rs] += add[o];add[o] = 0;}}void build(int o, int L, int R){if(L == R) {g[o] = b[L];return;}int mid = (L + R) >> 1;build(lson);build(rson);pushup(o);}void build2(int o, int L, int R){lazy[o] = add[o] = 0;if(L == R) {val[o] = a[L];return;}int mid = (L + R) >> 1;build2(lson);build2(rson);}void update1(int o, int L, int R, int ql, int qr, LL v){if(ql <= L && qr >= R) {val[o] = -val[o];add[o] = -add[o];val[o] += v;add[o] += v;lazy[o] ^= 1;return;}pushdown(o);int mid = (L + R) >> 1;if(ql <= mid) update1(lson, ql, qr, v);if(qr > mid) update1(rson, ql, qr, v);}void update2(int o, int L, int R, int q, LL v){if(L == R) {g[o] = v;return;}int mid = (L + R) >> 1;if(q <= mid) update2(lson, q, v);else update2(rson, q, v);pushup(o);}LL query1(int o, int L, int R, int q){if(L == R) return val[o];pushdown(o);int mid = (L + R) >> 1;if(q <= mid) return query1(lson, q);else return query1(rson, q);}LL query2(int o, int L, int R, int ql, int qr){if(ql <= L && qr >= R) return g[o];int mid = (L + R) >> 1;LL ans = 0;if(ql <= mid) ans = __gcd(ans, query2(lson, ql, qr));if(qr > mid) ans = __gcd(ans, query2(rson, ql, qr));return ans;}void work(){for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);b[1] = a[1];for(int i = 2; i <= n; i++) b[i] = a[i] - a[i-1];build(1, 1, n);build2(1, 1, n);while(m--) {int ql, qr, op;LL v;scanf("%d", &op);scanf("%d%d", &ql, &qr);if(op == 1) {scanf("%lld", &v);update1(1, 1, n, ql, qr, v);if(ql == 1) {LL t = query1(1, 1, n, ql);update2(1, 1, n, ql, t);}else {LL t1 = query1(1, 1, n, ql-1);LL t2 = query1(1, 1, n, ql);update2(1, 1, n, ql, t2 - t1);}if(qr < n) {LL t1 = query1(1, 1, n, qr);LL t2 = query1(1, 1, n, qr + 1);update2(1, 1, n, qr + 1, t2 - t1);}}else {LL ans = query1(1, 1, n, ql);ql++;if(ql <= qr) {LL t = query2(1, 1, n, ql, qr);if(t < 0) t = (t % ans + ans) % ans;ans = __gcd(ans, t);}printf("%lld\n", ans);}}}int main(){//freopen("data", "r", stdin);while(scanf("%d%d", &n, &m) != EOF) {work();}return 0;}


0 0
原创粉丝点击