CSES Range Queries: Polynomial Queries

Revision en2, by SilverSurge, 2023-10-29 22:32:18

I have been trying out the problem for a long time. the problem can be found here ( https://cses.fi/problemset/task/1736/ ). I hope someone can help me figure out my mistake. Thankyou in advance.

My Approach

I used a segment tree with lazy propagation. The Lazy Tree node contains if there is some addition in the corresponding interval and if there is what does it start with, the total can be calculated using simple arithmetic progression formula.

My Code

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

#define fastio ios::sync_with_stdio(false);cin.tie(NULL)
#define int long long
int INF = 1e18;
int NINF = -1e18;
int MOD = 1000000000+7;

class LazyDS
{
public:
    bool flag = false;
    int a = 0;
};
 
class SegDS
{
public:
    int sum;
};
 
class LazySegmentTree
{
private:
    vector<SegDS> stree;
    vector<LazyDS> ltree;
public:
    int n;
    vector<int> base;
 
    LazySegmentTree(int _n)
    {
        n = _n;
        base.assign(n, 0ll);
        ltree.assign(4*n, LazyDS());
        stree.assign(4*n, SegDS());
    }
 
    void init()
    {
        init(0, n-1, 1);
    }
 
    void init(int tl, int tr, int idx)
    {
        if(tl == tr)
        {
            stree[idx].sum = base[tl];
        }
        else
        {
            int tm = tl + (tr-tl)/2;
            init(tl, tm, 2*idx);
            init(tm+1, tr, 2*idx+1);
            stree[idx] = merge_seg_ds(stree[2*idx], stree[2*idx+1]);
        }
    }
 
    LazyDS merge_lazy_ds(LazyDS a, LazyDS b)
    {
        if(a.flag == false)
            return b;
        if(b.flag == false)
            return a;
        a.a += b.a;
        return a;
    }
 
    SegDS merge_seg_ds(SegDS a, SegDS b)
    {
        a.sum += b.sum;
        return a;
    }
 
    void push(int tl, int tr, int idx)
    {
        if(!ltree[idx].flag)
            return;

        int a = ltree[idx].a;
        int n = tr - tl + 1;
        stree[idx].sum += (n*(2*a + (n-1)))/2;
        if(tl != tr)
        {
            LazyDS lds = LazyDS();

            lds.flag = true;
            lds.a = a;
            ltree[2*idx] = merge_lazy_ds(ltree[2*idx], lds); 
            
            int tm = tl + (tr-tl)/2;
            lds.a = a + tm + 1 - tl;
            ltree[2*idx+1] = merge_lazy_ds(ltree[2*idx+1], lds); 
            // tm + 1 - tl = x - a
        }
        ltree[idx] = LazyDS();
    }
 
    void update(int l,int r)
    {
        update(0, n-1, 1, l, r);
    }
 
    void update(int tl, int tr, int idx, int l, int r)
    {
        push(tl, tr, idx);
        
        if(l > tr || r < tl)
            return;
        if(l <= tl && tr <= r)
        {
            // do what ever you want
            LazyDS lds = LazyDS();
            lds.flag = true;
            lds.a = tl - l + 1;
            // cout << "{"<< tl << ", " << tr << ", " << lds.a << ", " << tr-tl+1 << "}" << endl;
            // l l+1 ...... tl
            // 1 2          x
            // tl - l = x - 1
            ltree[idx] = merge_lazy_ds(ltree[idx], lds);
            push(tl, tr, idx);
        }
        else
        {
            int tm = tl + (tr-tl)/2;
            update(tl, tm, 2*idx, l, r);
            update(tm+1, tr, 2*idx+1, l, r);
            stree[idx] = merge_seg_ds(stree[2*idx], stree[2*idx+1]);
            ltree[idx] = LazyDS();
        }
    }
 
    SegDS query(int l, int r)
    {
        return query(0, n-1, 1, l, r);
    }
 
    SegDS query(int tl, int tr, int idx, int l, int r)
    {
        // return the appropriate base case
        push(tl, tr, idx);
 
        if(l > tr || r < tl)
            return SegDS();  
 
        if(l <= tl && tr <= r) 
        {
            return stree[idx];
        }
        int  tm = tl + (tr-tl)/2;
        SegDS left = query(tl, tm, 2*idx, l, r);
        SegDS right = query(tm+1, tr, 2*idx+1, l, r);
        return merge_seg_ds(left, right);
    }
};


void solve();

int32_t main()
{
    fastio;
    int tests = 1;
    // cin >> tests;
    while(tests--)
    {
        solve();
    }
    return 0;
}

void solve()
{
    int n, q;
    cin >> n >> q;
 
    LazySegmentTree lstree(n);
    for(int i=0;i<n;i++)
    {
        cin >> lstree.base[i];
    }
    lstree.init();
    // cout << "init finished" << endl;
    // return ;
    // cout << lstree.query(0, n-1).val << endl;
    // cout << lstree.query(0, n-1).val << endl;
    while(q--)
    {
        int type; cin >> type;
        if(type == 1)
        {
            int l, r;
            cin >> l >> r;
            l--; r--;
            // cout << "(" << l <<", " <<r <<")" << endl;
            lstree.update(l, r);
            // lstree.query(l, r);
        }
        else if(type == 2)
        {
            int l, r;
            cin >> l >> r;
            l--; r--;
            // cout << "(" << l <<", " <<r <<")" << endl;
            cout << lstree.query(l, r).sum << endl;
        }

        // for(int i=0;i<n;i++)
        //     lstree.query(i,i);

    }
}
Tags segment tree, cses range queries

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en4 English SilverSurge 2023-10-30 12:33:50 0 (published)
en3 English SilverSurge 2023-10-30 12:33:16 6880 (saved to drafts)
en2 English SilverSurge 2023-10-29 22:32:18 0 (published)
en1 English SilverSurge 2023-10-29 22:30:49 5231 Initial revision (saved to drafts)