非递归线段树代码。大致思路就是将数轴离散化,每次整个区间加,再查询区间,区间赋值。add标记是加,era标记是是否清空,val是该区间一天长出果实的量。
写完交上去直接 WA 了 24 个点,但是和榜一代码对拍了将近一天没有拍出来,大数据小数据都试过了。有这么离谱么...
代码如下,求大佬们帮调orz
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define F first
#define S second
using namespace std;
const ll MOD=998244353;
const ll inv2=499122177;
int q,segh;
ll n,d[200005],L[200005],R[200005],val[800005],sum[800005],add[400005];
bool era[400005];
ll getsum(ll l,ll r){
l%=MOD,r%=MOD;
return (l+r)%MOD*((r-l+1+MOD)%MOD)%MOD*inv2%MOD;
}
void Apply(int p,ll x)
{
if (x==-1)
{
sum[p]=add[p]=0ll;
if (p<n)
era[p]=1;
}
else
{
x%=MOD;
sum[p]=(sum[p]+x*val[p]%MOD)%MOD;
if (p<n)
add[p]=(add[p]+x)%MOD;
}
}
void calc(int p)
{
if (era[p])
sum[p]=0ll;
else
sum[p]=(sum[p<<1]+sum[p<<1|1]+add[p]*val[p]%MOD)%MOD;
}
void build(int l,int r)
{
for(l+=n,r+=n-1;l>1;)
{
l>>=1,r>>=1;
for(int i=r;i>=l;i--)
calc(i);
}
}
void push(int l,int r)
{
l+=n,r+=n-1;
for(int h=segh;h;h--)
for(int i=l>>h;i<=r>>h;i++)
{
if (era[i])
{
Apply(i<<1,-1);
Apply(i<<1|1,-1);
era[i]=0;
}
if (add[i])
{
Apply(i<<1,add[i]);
Apply(i<<1|1,add[i]);
add[i]=0ll;
}
}
}
void modify(int l,int r,ll x)
{
int l0=l,r0=r;
push(l,l+1),push(r-1,r);
for(l+=n,r+=n;l<r;l>>=1,r>>=1)
{
if (l&1) Apply(l++,x);
if (r&1) Apply(--r,x);
}
build(l0,l0+1),build(r0-1,r0);
}
ll query(int l,int r)
{
ll res=0ll;
push(l,l+1),push(r-1,r);
for(l+=n,r+=n;l<r;l>>=1,r>>=1)
{
if (l&1) res=(res+sum[l++])%MOD;
if (r&1) res=(res+sum[--r])%MOD;
}
return res;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(nullptr);
cin>>n>>q;
vector<ll> b;
for(int i=1;i<=q;i++)
{
cin>>d[i]>>L[i]>>R[i];
b.pb(L[i]),b.pb(R[i]+1);
}
sort(b.begin(),b.end());
b.erase(unique(b.begin(),b.end()),b.end());
n=b.size();
segh=(int)(sizeof(ll)*8-__builtin_clzll(n));
b.pb(b.back()+1);
for(int i=0;i<n-1;i++)
val[i+n]=getsum(b[i],b[i+1]-1);
for(int i=n-1;i;i--)
val[i]=(val[i<<1]+val[i<<1|1])%MOD;
for(int i=1;i<=q;i++)
{
L[i]=lower_bound(b.begin(),b.end(),L[i])-b.begin();
R[i]=lower_bound(b.begin(),b.end(),R[i]+1)-b.begin();
modify(0,n,d[i]-d[i-1]);
cout<<query(L[i],R[i])<<endl;
modify(L[i],R[i],-1);
}
return 0;
}