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