In this HackerEarth Greatest common divisor problem solution, you are given array A. There are 4 types of operations associated with it:
  1. l r x, for each i ∈ [l, r] replace ai with the value of x.
  2. l r x, for each i ∈ [l, r] replace ai with the value of the gcd(ai, x) function.
  3. l r, print the value of max ai, l ≤ i ≤ r.
  4. l r, print the value of al + al+1 + ... + ar.
The greatest common divisor (gcd(a, b)) of two positive integers a and b is equal to the biggest integer d such that both integers a and b are divisible by d.


HackerEarth Greatest common divisor problem solution


HackerEarth Greatest common divisor problem solution.

#include<bits/stdc++.h>
using namespace std;

const int MAX_N = 2e5 + 111;

struct node{
    long long sum;
    int element;
    int mx;
    int lz;
    int l, r;

    node(){
        element = -1;
        sum = 0;
        mx = 0;
        lz = -1;
        l = 0;
        r = 0;
    }

    node(int value){
        element = value;
        sum = value;
        mx = value;
    }

};

node t[4 * MAX_N];
int a[MAX_N];
int n, q;

inline node merge(node a, node b){
    node c = node();

    c.sum = a.sum + b.sum;

    c.mx = max(a.mx, b.mx);
    if(a.element == b.element && a.element > 0)
        c.element = a.element; else c.element = -1;

    return c;
}

void build(int v,int tl,int tr){
    if(tl == tr){
        t[v] = node(a[tl]);
        t[v].l = t[v].r = tl;
        return;
    }
    int tm = (tl + tr) >> 1,
        L = v << 1,
        R = L | 1;
    build(L, tl, tm);
    build(R, tm + 1, tr);
    t[v] = merge(t[L],t[R]);
    t[v].l = tl;
    t[v].r = tr;
}

inline void assignment(int v,int val){
    t[v].lz = val;
    t[v].sum = (t[v].r - t[v].l + 1) *1ll* val;
    t[v].mx = val;
    t[v].element = val;
}

inline void push(int v,int L,int R){
    if(t[v].lz != -1){
        if(t[v].l != t[v].r){
            assignment(L, t[v].lz);
            assignment(R, t[v].lz);
            int l = t[v].l,
                r = t[v].r;
            t[v] = merge(t[L],t[R]);
            t[v].l = l;
            t[v].r = r;
        }
        t[v].lz = -1;
    }
}

void update1(int v,int l,int r,int val){
    if(t[v].l > r || t[v].r < l)return;
    if(t[v].l >= l && t[v].r <= r){
        assignment(v, val);
        return;
    }
    int L = v << 1,
        R = L | 1;
    push(v, L, R);
    update1(L, l, r, val);
    update1(R, l, r, val);
    int l_ = t[v].l,
        r_ = t[v].r;
    t[v] = merge(t[L], t[R]);
    t[v].l = l_;
    t[v].r = r_;
}

void update2(int v,int l,int r,int val){
    if(t[v].l > r || t[v].r < l)return;
    if(t[v].l >= l && t[v].r <= r && t[v].element > 0){
        assignment(v, __gcd(val, t[v].element));
        return;
    }
    int L = v << 1,
        R = L | 1;
    push(v, L, R);
    update2(L, l, r, val);
    update2(R, l, r, val);
    int l_ = t[v].l,
        r_ = t[v].r;
    t[v] = merge(t[L], t[R]);
    t[v].l = l_;
    t[v].r = r_;
}

node NULL_;

node get(int v,int l,int r){
    if(t[v].l > r || t[v].r < l)return NULL_;
    int L = v << 1,
        R = L | 1;
    push(v, L, R);
    if(t[v].l >= l && t[v].r <= r)return t[v];
    int tm = (t[v].l + t[v].r) >> 1;
    if(r <= tm)return get(L, l, r);
    if(l > tm)return get(R, l, r);
    node ans1 = get(L, l, r),
         ans2 = get(R, l, r);
    node ans = merge(ans1, ans2);
    return ans;
}

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

   // freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; ++i){
        cin >> a[i];
    }

    build(1, 1, n);

    while(q-->0){
        int type, l, r;
        cin >> type >> l >> r;
        if(type == 1){
            int x;
            cin >> x;
            update1(1, l, r, x);
        }else
        if(type == 2)
        {
            int x;
            cin >> x;
            update2(1, l, r, x);
        }else{
            if(type == 3)cout << get(1, l, r).mx << '\n';
                else cout << get(1, l, r).sum << '\n';
        }
    }

    return 0;
}