CSES Range Queries: Polynomial Queries

Правка en1, от SilverSurge, 2023-10-29 22:30:49

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);

    }
}
Теги segment tree, cses range queries

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en4 Английский SilverSurge 2023-10-30 12:33:50 0 (published)
en3 Английский SilverSurge 2023-10-30 12:33:16 6880 (saved to drafts)
en2 Английский SilverSurge 2023-10-29 22:32:18 0 (published)
en1 Английский SilverSurge 2023-10-29 22:30:49 5231 Initial revision (saved to drafts)