2023河南萌新联赛第(三)场:郑州大学A

1:算法:线段树懒标记

2:思路:

由题意可知,他的工资每月都在发,所以我们可以做两个操作

1:每次加工资,进行一次加,这相当于区间加,直接套模板设为sum

2:每次加工资我把他加的值直接算到最后一次加工资,然后在用线段树加起来,需要查询的时候减去sum*(总的月数-当前月数)

代码

点击查看代码
#include <bits/stdc++.h>

using namespace std;

#define int long long
const int N = 1e6 + 10;
const int md = 998244353;
#define ls idx*2
#define rs idx*2+1
int n,m;
struct now{
    int sum;//涨的工资
    int sum1;//总的工资
}seg[N*4];
struct node{
    int su;//涨的工资
    int su1;//总的工资
}teg[N*4];
void update(int idx)
{
    seg[idx].sum = (seg[ls].sum + seg[rs].sum)%md;
    seg[idx].sum1 = (seg[ls].sum1 + seg[rs].sum1)%md;
}
void pushdown(int idx,int l,int r)
{
    int mid = (l+r)/2;
    seg[ls].sum = (seg[ls].sum + teg[idx].su*(mid-l+1)%md)%md;
    seg[rs].sum = (seg[rs].sum + teg[idx].su*(r-mid)%md)%md;
    seg[ls].sum1 = (seg[ls].sum1 + teg[idx].su1*(mid-l+1)%md)%md;
    seg[rs].sum1 = (seg[rs].sum1 + teg[idx].su1*(r-mid)%md)%md;
    
    teg[ls].su = (teg[ls].su + teg[idx].su)%md;
    teg[rs].su = (teg[rs].su + teg[idx].su)%md;
    teg[ls].su1 = (teg[ls].su1 + teg[idx].su1)%md;
    teg[rs].su1 = (teg[rs].su1 + teg[idx].su1)%md;
    teg[idx].su = teg[idx].su1 = 0;
}
void build(int idx,int l,int r)
{
    if(l == r)
    {
        seg[idx].sum = seg[idx].sum1 = 0;
        return;
    }        
    int mid = (l+r)/2;
    build(ls,l,mid);
    build(rs,mid+1,r);
    update(idx);
}
void modify(int idx,int l,int r,int ql,int qr,int val,int data)
{
    if(ql<= l&& qr>=r)
    {
        seg[idx].sum =  (seg[idx].sum + (r-l+1)*val%md)%md;
        seg[idx].sum1 = (seg[idx].sum1 + (r-l+1)*val%md*(m-data+1)%md)%md;
        teg[idx].su = (teg[idx].su+val)%md;
        teg[idx].su1 = (teg[idx].su1 + val*(m-data+1)%md)%md;
        return;
    }
    pushdown(idx,l,r);
    int mid = (l+r)/2;
    if(ql <= mid)
        modify(ls,l,mid,ql,qr,val,data);
    if(qr > mid)
        modify(rs,mid+1,r,ql,qr,val,data);
    update(idx);
}

int query(int idx,int l,int r,int ql,int qr,int data)
{
    if(l >= ql && r <= qr)
    {
       int w = (seg[idx].sum1 - seg[idx].sum*(m-data)%md+md)%md;
        return w;
    }
    else
    {
        pushdown(idx,l,r);
        int ans = 0;
        int mid = (l+r)/2;
        if(mid < qr)
            ans = (ans+query(idx*2+1,mid+1,r,ql,qr,data))%md;
        if(mid >= ql)
            ans = (ans+query(idx*2,l,mid,ql,qr,data))%md;
        return ans;
    }
}
void solve()
{
    cin >> n >> m;
    build(1,1,n);
    for(int i = 1;i <= m;i ++)
    {
        int op,x,y;
        cin >> op >> x >> y;
        if(op == 0)
        {
            int val;
            cin >> val;
            modify(1,1,n,x,y,val,i);
        }
        else
        {
            cout << query(1,1,n,x,y,i)%md<<'\n';
        }
            
    }
}
signed main()
{
    solve();
}
posted @ 2023-07-27 10:40  清初  阅读(51)  评论(0)    收藏  举报