12.2日志

发布于:2025-02-11 ⋅ 阅读:(37) ⋅ 点赞:(0)

1.P1438 无聊的数列 - 洛谷 | 计算机科学教育新生态

线段树 + 差分,一开始的思路是直接将整个等差数列加到线段树中,但是pushdown不好维护于是改变思路,想到我们可以去维护a的差分数组,这样一来对[l , r]加上一个首项为看,公差为d的等差数列其实就是在l上加k,[l + 1 ~ r]上加d,之后我们求第p项也转变成求[1 ~ p]的区间和即可,一开始多尝试新思路,不要在困难的思路上折磨自己,多想少code

#define yyy cout<<"Yes"<<"\n" 
#define nnn cout<<"No"<<"\n" 
#define x first 
#define y second
#include<bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef pair<ll , ll> pii;
typedef pair<int , string> pis;
const int N = 1e5 + 10,inf = 0x3f3f3f3f,mod = 1e9 + 7;
const double pi = 3.1415926535898;

struct node
{
    int l,r;
    ll sum,add;
}tr[4 * N];

int n,m;
ll a[N],b[N];

void pushup(node &u,node &l,node &r)
{
    u.sum = l.sum + r.sum;
}

void pushup(int u)
{
    pushup(tr[u] , tr[u << 1] , tr[u << 1 | 1]);
}

void pushdown(node &u,node &l,node &r)
{
    if(u.add)
    {
        l.sum += (l.r - l.l + 1) * u.add;
        r.sum += (r.r - r.l + 1) * u.add;
        l.add += u.add,r.add += u.add;
        u.add = 0;
    }
}

void pushdown(int u)
{
    pushdown(tr[u] , tr[u << 1] , tr[u << 1 | 1]);
}

void build(int u,int l,int r)
{
    if(l == r)
    {
        tr[u] = {l , r , b[l] , 0};
    }else
    {
        tr[u] = {l , r};
        int mid = (l + r) / 2;
        build(u << 1 , l , mid);
        build(u << 1 | 1 , mid + 1 , r);
        pushup(u);
    }
}

void modify(int u,int l,int r,ll d)
{
    if(tr[u].l >= l && tr[u].r <= r)
    {
        tr[u].sum += (tr[u].r - tr[u].l + 1) * d;
        tr[u].add += d;
    }else
    {
        int mid = (tr[u].l + tr[u].r) / 2;
        pushdown(u);
        if(l <= mid)
        {
            modify(u << 1 , l , r , d);
        }
        if(r > mid)
        {
            modify(u << 1 | 1 , l , r , d);
        }
        pushup(u);
    }
}

node query(int u,int l,int r)
{
    if(tr[u].l >= l && tr[u].r <= r)
    {
        return tr[u];
    }else
    {
        int mid = (tr[u].l + tr[u].r) / 2;
        pushdown(u);
        if(r <= mid)
        {
            return query(u << 1 , l , r);
        }else if(l > mid)
        {
            return query(u << 1 | 1 , l , r);
        }else
        {
            node left = query(u << 1 , l , r);
            node right = query(u << 1 | 1 , l , r);
            node res;
            pushup(res , left , right);
            return res;
        }
    }
}

int main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

    cin>>n>>m;
    for(int i = 1 ; i <= n ; i++)
    {
        cin>>a[i];
        b[i] = a[i] - a[i - 1];
    }        

    build(1 , 1 , n);

    while(m--)
    {
        int op;
        cin>>op;
        if(op == 1)
        {
            ll l,r,d,k;
            cin>>l>>r>>k>>d;
            modify(1 , l , l , k);
            if(r + 1 <= n)
            {
                modify(1 , r + 1 , r + 1 , - k);
            }
            if(r > l)
            {
                modify(1 , l + 1 , r , d);
                if(r + 1 <= n)
                {
                    modify(1 , r + 1 , r + 1 , -d * (r - l));
                }   
            }
        }else
        {
            int p;
            cin>>p;
            cout<<query(1 , 1 , p).sum<<"\n";
        }
    }
    return 0;
}


// 5 8
// 1 2 3 4 5
// 1 2 4 1 2
// 1 3 5 4 9
// 1 1 2 1 2
// 2 1
// 2 2
// 2 3
// 2 4
// 2 5

// 2 
// 6
// 10
// 22
// 27

网站公告

今日签到

点亮在社区的每一天
去签到